@react-native/codegen 0.73.0 → 0.74.0-nightly-20231003-5dedf277c

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/README.md +2 -2
  2. package/lib/CodegenSchema.d.ts +15 -4
  3. package/lib/CodegenSchema.js.flow +33 -21
  4. package/lib/cli/combine/combine-js-to-schema-cli.js +7 -1
  5. package/lib/cli/combine/combine-js-to-schema-cli.js.flow +7 -1
  6. package/lib/generators/components/CppHelpers.js +39 -2
  7. package/lib/generators/components/CppHelpers.js.flow +54 -5
  8. package/lib/generators/components/GenerateEventEmitterCpp.js +222 -28
  9. package/lib/generators/components/GenerateEventEmitterCpp.js.flow +221 -34
  10. package/lib/generators/components/GenerateEventEmitterH.js +77 -26
  11. package/lib/generators/components/GenerateEventEmitterH.js.flow +87 -30
  12. package/lib/generators/components/GeneratePropsH.js +2 -3
  13. package/lib/generators/components/GeneratePropsH.js.flow +2 -3
  14. package/lib/generators/components/GeneratePropsJavaPojo/PojoCollector.js +0 -1
  15. package/lib/generators/components/GeneratePropsJavaPojo/PojoCollector.js.flow +3 -5
  16. package/lib/generators/components/GenerateThirdPartyFabricComponentsProviderH.js +4 -0
  17. package/lib/generators/components/GenerateThirdPartyFabricComponentsProviderH.js.flow +4 -0
  18. package/lib/generators/components/GenerateThirdPartyFabricComponentsProviderObjCpp.js +2 -0
  19. package/lib/generators/components/GenerateThirdPartyFabricComponentsProviderObjCpp.js.flow +2 -0
  20. package/lib/generators/components/__test_fixtures__/fixtures.js +114 -1
  21. package/lib/generators/components/__test_fixtures__/fixtures.js.flow +114 -1
  22. package/lib/generators/modules/GenerateModuleCpp.js +1 -1
  23. package/lib/generators/modules/GenerateModuleCpp.js.flow +1 -1
  24. package/lib/generators/modules/GenerateModuleH.js +44 -39
  25. package/lib/generators/modules/GenerateModuleH.js.flow +51 -39
  26. package/lib/generators/modules/GenerateModuleJavaSpec.js +9 -7
  27. package/lib/generators/modules/GenerateModuleJavaSpec.js.flow +10 -6
  28. package/lib/generators/modules/GenerateModuleJniH.js +1 -1
  29. package/lib/generators/modules/GenerateModuleJniH.js.flow +1 -1
  30. package/lib/generators/modules/GenerateModuleObjCpp/serializeMethod.js +11 -3
  31. package/lib/generators/modules/GenerateModuleObjCpp/serializeMethod.js.flow +13 -3
  32. package/lib/parsers/error-utils.js +44 -0
  33. package/lib/parsers/error-utils.js.flow +59 -0
  34. package/lib/parsers/errors.js +3 -9
  35. package/lib/parsers/errors.js.flow +3 -9
  36. package/lib/parsers/flow/components/__test_fixtures__/fixtures.js +51 -0
  37. package/lib/parsers/flow/components/__test_fixtures__/fixtures.js.flow +51 -0
  38. package/lib/parsers/flow/components/componentsUtils.js +22 -33
  39. package/lib/parsers/flow/components/componentsUtils.js.flow +24 -45
  40. package/lib/parsers/flow/components/events.js +151 -128
  41. package/lib/parsers/flow/components/events.js.flow +161 -136
  42. package/lib/parsers/flow/components/index.js +13 -94
  43. package/lib/parsers/flow/components/index.js.flow +5 -102
  44. package/lib/parsers/flow/modules/index.js +24 -24
  45. package/lib/parsers/flow/modules/index.js.flow +6 -6
  46. package/lib/parsers/flow/parser.d.ts +9 -2
  47. package/lib/parsers/flow/parser.js +179 -18
  48. package/lib/parsers/flow/parser.js.flow +231 -7
  49. package/lib/parsers/flow/utils.js +0 -63
  50. package/lib/parsers/flow/utils.js.flow +1 -77
  51. package/lib/parsers/parser.js.flow +176 -3
  52. package/lib/parsers/parserMock.js +202 -4
  53. package/lib/parsers/parserMock.js.flow +253 -4
  54. package/lib/parsers/parsers-commons.js +268 -10
  55. package/lib/parsers/parsers-commons.js.flow +365 -12
  56. package/lib/parsers/parsers-primitives.js +95 -1
  57. package/lib/parsers/parsers-primitives.js.flow +136 -1
  58. package/lib/parsers/typescript/components/__test_fixtures__/fixtures.js +51 -0
  59. package/lib/parsers/typescript/components/__test_fixtures__/fixtures.js.flow +51 -0
  60. package/lib/parsers/typescript/components/componentsUtils.js +49 -57
  61. package/lib/parsers/typescript/components/componentsUtils.js.flow +48 -66
  62. package/lib/parsers/typescript/components/events.js +136 -115
  63. package/lib/parsers/typescript/components/events.js.flow +148 -119
  64. package/lib/parsers/typescript/components/extends.js +2 -49
  65. package/lib/parsers/typescript/components/extends.js.flow +1 -55
  66. package/lib/parsers/typescript/components/index.js +14 -99
  67. package/lib/parsers/typescript/components/index.js.flow +6 -106
  68. package/lib/parsers/typescript/modules/index.js +28 -26
  69. package/lib/parsers/typescript/modules/index.js.flow +9 -8
  70. package/lib/parsers/typescript/parser.d.ts +9 -2
  71. package/lib/parsers/typescript/parser.js +208 -14
  72. package/lib/parsers/typescript/parser.js.flow +247 -8
  73. package/lib/parsers/utils.js.flow +6 -0
  74. package/package.json +27 -16
  75. package/lib/parsers/flow/components/extends.js +0 -52
  76. package/lib/parsers/flow/components/extends.js.flow +0 -66
  77. package/lib/parsers/flow/components/props.js +0 -47
  78. package/lib/parsers/flow/components/props.js.flow +0 -60
  79. package/lib/parsers/typescript/components/props.js +0 -39
  80. package/lib/parsers/typescript/components/props.js.flow +0 -48
  81. package/lib/parsers/typescript/utils.js +0 -90
  82. package/lib/parsers/typescript/utils.js.flow +0 -104
@@ -10,9 +10,11 @@
10
10
 
11
11
  'use strict';
12
12
 
13
- const _require = require('./CppHelpers.js'),
13
+ const _require = require('./CppHelpers'),
14
14
  generateEventStructName = _require.generateEventStructName;
15
- const FileTemplate = ({events, libraryName}) => `
15
+ const _require2 = require('../Utils'),
16
+ indent = _require2.indent;
17
+ const FileTemplate = ({events, libraryName, extraIncludes}) => `
16
18
  /**
17
19
  * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
18
20
  *
@@ -23,6 +25,7 @@ const FileTemplate = ({events, libraryName}) => `
23
25
  */
24
26
 
25
27
  #include <react/renderer/components/${libraryName}/EventEmitters.h>
28
+ ${[...extraIncludes].join('\n')}
26
29
 
27
30
  namespace facebook {
28
31
  namespace react {
@@ -54,39 +57,200 @@ void ${className}EventEmitter::${eventName}() const {
54
57
  dispatchEvent("${dispatchEventName}");
55
58
  }
56
59
  `.trim();
57
- function generateSetter(variableName, propertyName, propertyParts) {
58
- const trailingPeriod = propertyParts.length === 0 ? '' : '.';
59
- const eventChain = `$event.${propertyParts.join(
60
- '.',
61
- )}${trailingPeriod}${propertyName});`;
62
- return `${variableName}.setProperty(runtime, "${propertyName}", ${eventChain}`;
63
- }
64
- function generateEnumSetter(variableName, propertyName, propertyParts) {
65
- const trailingPeriod = propertyParts.length === 0 ? '' : '.';
66
- const eventChain = `$event.${propertyParts.join(
67
- '.',
68
- )}${trailingPeriod}${propertyName})`;
69
- return `${variableName}.setProperty(runtime, "${propertyName}", toString(${eventChain});`;
60
+ function generateSetter(
61
+ variableName,
62
+ propertyName,
63
+ propertyParts,
64
+ usingEvent,
65
+ valueMapper = value => value,
66
+ ) {
67
+ const eventChain = usingEvent
68
+ ? `$event.${[...propertyParts, propertyName].join('.')}`
69
+ : [propertyParts, propertyName].join('.');
70
+ return `${variableName}.setProperty(runtime, "${propertyName}", ${valueMapper(
71
+ eventChain,
72
+ )});`;
70
73
  }
71
74
  function generateObjectSetter(
72
75
  variableName,
73
76
  propertyName,
74
77
  propertyParts,
75
78
  typeAnnotation,
79
+ extraIncludes,
80
+ usingEvent,
76
81
  ) {
77
82
  return `
78
83
  {
79
84
  auto ${propertyName} = jsi::Object(runtime);
80
- ${generateSetters(
81
- propertyName,
82
- typeAnnotation.properties,
83
- propertyParts.concat([propertyName]),
85
+ ${indent(
86
+ generateSetters(
87
+ propertyName,
88
+ typeAnnotation.properties,
89
+ propertyParts.concat([propertyName]),
90
+ extraIncludes,
91
+ usingEvent,
92
+ ),
93
+ 2,
84
94
  )}
85
95
  ${variableName}.setProperty(runtime, "${propertyName}", ${propertyName});
86
96
  }
87
97
  `.trim();
88
98
  }
89
- function generateSetters(parentPropertyName, properties, propertyParts) {
99
+ function setValueAtIndex(
100
+ propertyName,
101
+ indexVariable,
102
+ loopLocalVariable,
103
+ mappingFunction = value => value,
104
+ ) {
105
+ return `${propertyName}.setValueAtIndex(runtime, ${indexVariable}++, ${mappingFunction(
106
+ loopLocalVariable,
107
+ )});`;
108
+ }
109
+ function generateArraySetter(
110
+ variableName,
111
+ propertyName,
112
+ propertyParts,
113
+ elementType,
114
+ extraIncludes,
115
+ usingEvent,
116
+ ) {
117
+ const eventChain = usingEvent
118
+ ? `$event.${[...propertyParts, propertyName].join('.')}`
119
+ : [propertyParts, propertyName].join('.');
120
+ const indexVar = `${propertyName}Index`;
121
+ const innerLoopVar = `${propertyName}Value`;
122
+ return `
123
+ auto ${propertyName} = jsi::Array(runtime, ${eventChain}.size());
124
+ size_t ${indexVar} = 0;
125
+ for (auto ${innerLoopVar} : ${eventChain}) {
126
+ ${handleArrayElementType(
127
+ elementType,
128
+ propertyName,
129
+ indexVar,
130
+ innerLoopVar,
131
+ propertyParts,
132
+ extraIncludes,
133
+ usingEvent,
134
+ )}
135
+ }
136
+ ${variableName}.setProperty(runtime, "${propertyName}", ${propertyName});
137
+ `;
138
+ }
139
+ function handleArrayElementType(
140
+ elementType,
141
+ propertyName,
142
+ indexVariable,
143
+ loopLocalVariable,
144
+ propertyParts,
145
+ extraIncludes,
146
+ usingEvent,
147
+ ) {
148
+ switch (elementType.type) {
149
+ case 'BooleanTypeAnnotation':
150
+ return setValueAtIndex(
151
+ propertyName,
152
+ indexVariable,
153
+ loopLocalVariable,
154
+ val => `(bool)${val}`,
155
+ );
156
+ case 'StringTypeAnnotation':
157
+ case 'Int32TypeAnnotation':
158
+ case 'DoubleTypeAnnotation':
159
+ case 'FloatTypeAnnotation':
160
+ return setValueAtIndex(propertyName, indexVariable, loopLocalVariable);
161
+ case 'MixedTypeAnnotation':
162
+ return setValueAtIndex(
163
+ propertyName,
164
+ indexVariable,
165
+ loopLocalVariable,
166
+ val => `jsi::valueFromDynamic(runtime, ${val})`,
167
+ );
168
+ case 'StringEnumTypeAnnotation':
169
+ return setValueAtIndex(
170
+ propertyName,
171
+ indexVariable,
172
+ loopLocalVariable,
173
+ val => `toString(${val})`,
174
+ );
175
+ case 'ObjectTypeAnnotation':
176
+ return convertObjectTypeArray(
177
+ propertyName,
178
+ indexVariable,
179
+ loopLocalVariable,
180
+ propertyParts,
181
+ elementType,
182
+ extraIncludes,
183
+ );
184
+ case 'ArrayTypeAnnotation':
185
+ return convertArrayTypeArray(
186
+ propertyName,
187
+ indexVariable,
188
+ loopLocalVariable,
189
+ propertyParts,
190
+ elementType,
191
+ extraIncludes,
192
+ usingEvent,
193
+ );
194
+ default:
195
+ throw new Error(
196
+ `Received invalid elementType for array ${elementType.type}`,
197
+ );
198
+ }
199
+ }
200
+ function convertObjectTypeArray(
201
+ propertyName,
202
+ indexVariable,
203
+ loopLocalVariable,
204
+ propertyParts,
205
+ objectTypeAnnotation,
206
+ extraIncludes,
207
+ ) {
208
+ return `auto ${propertyName}Object = jsi::Object(runtime);
209
+ ${generateSetters(
210
+ `${propertyName}Object`,
211
+ objectTypeAnnotation.properties,
212
+ [].concat([loopLocalVariable]),
213
+ extraIncludes,
214
+ false,
215
+ )}
216
+ ${setValueAtIndex(propertyName, indexVariable, `${propertyName}Object`)}`;
217
+ }
218
+ function convertArrayTypeArray(
219
+ propertyName,
220
+ indexVariable,
221
+ loopLocalVariable,
222
+ propertyParts,
223
+ eventTypeAnnotation,
224
+ extraIncludes,
225
+ usingEvent,
226
+ ) {
227
+ if (eventTypeAnnotation.type !== 'ArrayTypeAnnotation') {
228
+ throw new Error(
229
+ `Inconsistent eventTypeAnnotation received. Expected type = 'ArrayTypeAnnotation'; received = ${eventTypeAnnotation.type}`,
230
+ );
231
+ }
232
+ return `auto ${propertyName}Array = jsi::Array(runtime, ${loopLocalVariable}.size());
233
+ size_t ${indexVariable}Internal = 0;
234
+ for (auto ${loopLocalVariable}Internal : ${loopLocalVariable}) {
235
+ ${handleArrayElementType(
236
+ eventTypeAnnotation.elementType,
237
+ `${propertyName}Array`,
238
+ `${indexVariable}Internal`,
239
+ `${loopLocalVariable}Internal`,
240
+ propertyParts,
241
+ extraIncludes,
242
+ usingEvent,
243
+ )}
244
+ }
245
+ ${setValueAtIndex(propertyName, indexVariable, `${propertyName}Array`)}`;
246
+ }
247
+ function generateSetters(
248
+ parentPropertyName,
249
+ properties,
250
+ propertyParts,
251
+ extraIncludes,
252
+ usingEvent = true,
253
+ ) {
90
254
  const propSetters = properties
91
255
  .map(eventProperty => {
92
256
  const typeAnnotation = eventProperty.typeAnnotation;
@@ -100,12 +264,24 @@ function generateSetters(parentPropertyName, properties, propertyParts) {
100
264
  parentPropertyName,
101
265
  eventProperty.name,
102
266
  propertyParts,
267
+ usingEvent,
268
+ );
269
+ case 'MixedTypeAnnotation':
270
+ extraIncludes.add('#include <jsi/JSIDynamic.h>');
271
+ return generateSetter(
272
+ parentPropertyName,
273
+ eventProperty.name,
274
+ propertyParts,
275
+ usingEvent,
276
+ prop => `jsi::valueFromDynamic(runtime, ${prop})`,
103
277
  );
104
278
  case 'StringEnumTypeAnnotation':
105
- return generateEnumSetter(
279
+ return generateSetter(
106
280
  parentPropertyName,
107
281
  eventProperty.name,
108
282
  propertyParts,
283
+ usingEvent,
284
+ prop => `toString(${prop})`,
109
285
  );
110
286
  case 'ObjectTypeAnnotation':
111
287
  return generateObjectSetter(
@@ -113,16 +289,29 @@ function generateSetters(parentPropertyName, properties, propertyParts) {
113
289
  eventProperty.name,
114
290
  propertyParts,
115
291
  typeAnnotation,
292
+ extraIncludes,
293
+ usingEvent,
294
+ );
295
+ case 'ArrayTypeAnnotation':
296
+ return generateArraySetter(
297
+ parentPropertyName,
298
+ eventProperty.name,
299
+ propertyParts,
300
+ typeAnnotation.elementType,
301
+ extraIncludes,
302
+ usingEvent,
116
303
  );
117
304
  default:
118
305
  typeAnnotation.type;
119
- throw new Error('Received invalid event property type');
306
+ throw new Error(
307
+ `Received invalid event property type ${typeAnnotation.type}`,
308
+ );
120
309
  }
121
310
  })
122
311
  .join('\n');
123
312
  return propSetters;
124
313
  }
125
- function generateEvent(componentName, event) {
314
+ function generateEvent(componentName, event, extraIncludes) {
126
315
  // This is a gross hack necessary because native code is sending
127
316
  // events named things like topChange to JS which is then converted back to
128
317
  // call the onChange prop. We should be consistent throughout the system.
@@ -135,7 +324,12 @@ function generateEvent(componentName, event) {
135
324
  if (event.typeAnnotation.argument) {
136
325
  const implementation = `
137
326
  auto $payload = jsi::Object(runtime);
138
- ${generateSetters('$payload', event.typeAnnotation.argument.properties, [])}
327
+ ${generateSetters(
328
+ '$payload',
329
+ event.typeAnnotation.argument.properties,
330
+ [],
331
+ extraIncludes,
332
+ )}
139
333
  return $payload;
140
334
  `.trim();
141
335
  if (!event.name.startsWith('on')) {
@@ -172,20 +366,20 @@ module.exports = {
172
366
  })
173
367
  .filter(Boolean)
174
368
  .reduce((acc, components) => Object.assign(acc, components), {});
175
- const fileName = 'EventEmitters.cpp';
369
+ const extraIncludes = new Set();
176
370
  const componentEmitters = Object.keys(moduleComponents)
177
371
  .map(componentName => {
178
372
  const component = moduleComponents[componentName];
179
373
  return component.events
180
- .map(event => {
181
- return generateEvent(componentName, event);
182
- })
374
+ .map(event => generateEvent(componentName, event, extraIncludes))
183
375
  .join('\n');
184
376
  })
185
377
  .join('\n');
378
+ const fileName = 'EventEmitters.cpp';
186
379
  const replacedTemplate = FileTemplate({
187
380
  libraryName,
188
381
  events: componentEmitters,
382
+ extraIncludes,
189
383
  });
190
384
  return new Map([[fileName, replacedTemplate]]);
191
385
  },
@@ -11,7 +11,8 @@
11
11
  'use strict';
12
12
  import type {EventTypeShape} from '../../CodegenSchema';
13
13
 
14
- const {generateEventStructName} = require('./CppHelpers.js');
14
+ const {generateEventStructName} = require('./CppHelpers');
15
+ const {indent} = require('../Utils');
15
16
 
16
17
  import type {
17
18
  ComponentShape,
@@ -32,9 +33,11 @@ type ComponentCollection = $ReadOnly<{
32
33
  const FileTemplate = ({
33
34
  events,
34
35
  libraryName,
36
+ extraIncludes,
35
37
  }: {
36
38
  events: string,
37
39
  libraryName: string,
40
+ extraIncludes: Set<string>,
38
41
  }) => `
39
42
  /**
40
43
  * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
@@ -46,6 +49,7 @@ const FileTemplate = ({
46
49
  */
47
50
 
48
51
  #include <react/renderer/components/${libraryName}/EventEmitters.h>
52
+ ${[...extraIncludes].join('\n')}
49
53
 
50
54
  namespace facebook {
51
55
  namespace react {
@@ -98,26 +102,15 @@ function generateSetter(
98
102
  variableName: string,
99
103
  propertyName: string,
100
104
  propertyParts: $ReadOnlyArray<string>,
105
+ usingEvent: boolean,
106
+ valueMapper: string => string = value => value,
101
107
  ) {
102
- const trailingPeriod = propertyParts.length === 0 ? '' : '.';
103
- const eventChain = `$event.${propertyParts.join(
104
- '.',
105
- )}${trailingPeriod}${propertyName});`;
106
-
107
- return `${variableName}.setProperty(runtime, "${propertyName}", ${eventChain}`;
108
- }
109
-
110
- function generateEnumSetter(
111
- variableName: string,
112
- propertyName: string,
113
- propertyParts: $ReadOnlyArray<string>,
114
- ) {
115
- const trailingPeriod = propertyParts.length === 0 ? '' : '.';
116
- const eventChain = `$event.${propertyParts.join(
117
- '.',
118
- )}${trailingPeriod}${propertyName})`;
119
-
120
- return `${variableName}.setProperty(runtime, "${propertyName}", toString(${eventChain});`;
108
+ const eventChain = usingEvent
109
+ ? `$event.${[...propertyParts, propertyName].join('.')}`
110
+ : [propertyParts, propertyName].join('.');
111
+ return `${variableName}.setProperty(runtime, "${propertyName}", ${valueMapper(
112
+ eventChain,
113
+ )});`;
121
114
  }
122
115
 
123
116
  function generateObjectSetter(
@@ -125,24 +118,186 @@ function generateObjectSetter(
125
118
  propertyName: string,
126
119
  propertyParts: $ReadOnlyArray<string>,
127
120
  typeAnnotation: ObjectTypeAnnotation<EventTypeAnnotation>,
121
+ extraIncludes: Set<string>,
122
+ usingEvent: boolean,
128
123
  ) {
129
124
  return `
130
125
  {
131
126
  auto ${propertyName} = jsi::Object(runtime);
132
- ${generateSetters(
133
- propertyName,
134
- typeAnnotation.properties,
135
- propertyParts.concat([propertyName]),
127
+ ${indent(
128
+ generateSetters(
129
+ propertyName,
130
+ typeAnnotation.properties,
131
+ propertyParts.concat([propertyName]),
132
+ extraIncludes,
133
+ usingEvent,
134
+ ),
135
+ 2,
136
136
  )}
137
137
  ${variableName}.setProperty(runtime, "${propertyName}", ${propertyName});
138
138
  }
139
139
  `.trim();
140
140
  }
141
141
 
142
+ function setValueAtIndex(
143
+ propertyName: string,
144
+ indexVariable: string,
145
+ loopLocalVariable: string,
146
+ mappingFunction: string => string = value => value,
147
+ ) {
148
+ return `${propertyName}.setValueAtIndex(runtime, ${indexVariable}++, ${mappingFunction(
149
+ loopLocalVariable,
150
+ )});`;
151
+ }
152
+
153
+ function generateArraySetter(
154
+ variableName: string,
155
+ propertyName: string,
156
+ propertyParts: $ReadOnlyArray<string>,
157
+ elementType: EventTypeAnnotation,
158
+ extraIncludes: Set<string>,
159
+ usingEvent: boolean,
160
+ ): string {
161
+ const eventChain = usingEvent
162
+ ? `$event.${[...propertyParts, propertyName].join('.')}`
163
+ : [propertyParts, propertyName].join('.');
164
+ const indexVar = `${propertyName}Index`;
165
+ const innerLoopVar = `${propertyName}Value`;
166
+ return `
167
+ auto ${propertyName} = jsi::Array(runtime, ${eventChain}.size());
168
+ size_t ${indexVar} = 0;
169
+ for (auto ${innerLoopVar} : ${eventChain}) {
170
+ ${handleArrayElementType(
171
+ elementType,
172
+ propertyName,
173
+ indexVar,
174
+ innerLoopVar,
175
+ propertyParts,
176
+ extraIncludes,
177
+ usingEvent,
178
+ )}
179
+ }
180
+ ${variableName}.setProperty(runtime, "${propertyName}", ${propertyName});
181
+ `;
182
+ }
183
+
184
+ function handleArrayElementType(
185
+ elementType: EventTypeAnnotation,
186
+ propertyName: string,
187
+ indexVariable: string,
188
+ loopLocalVariable: string,
189
+ propertyParts: $ReadOnlyArray<string>,
190
+ extraIncludes: Set<string>,
191
+ usingEvent: boolean,
192
+ ): string {
193
+ switch (elementType.type) {
194
+ case 'BooleanTypeAnnotation':
195
+ return setValueAtIndex(
196
+ propertyName,
197
+ indexVariable,
198
+ loopLocalVariable,
199
+ val => `(bool)${val}`,
200
+ );
201
+ case 'StringTypeAnnotation':
202
+ case 'Int32TypeAnnotation':
203
+ case 'DoubleTypeAnnotation':
204
+ case 'FloatTypeAnnotation':
205
+ return setValueAtIndex(propertyName, indexVariable, loopLocalVariable);
206
+ case 'MixedTypeAnnotation':
207
+ return setValueAtIndex(
208
+ propertyName,
209
+ indexVariable,
210
+ loopLocalVariable,
211
+ val => `jsi::valueFromDynamic(runtime, ${val})`,
212
+ );
213
+ case 'StringEnumTypeAnnotation':
214
+ return setValueAtIndex(
215
+ propertyName,
216
+ indexVariable,
217
+ loopLocalVariable,
218
+ val => `toString(${val})`,
219
+ );
220
+ case 'ObjectTypeAnnotation':
221
+ return convertObjectTypeArray(
222
+ propertyName,
223
+ indexVariable,
224
+ loopLocalVariable,
225
+ propertyParts,
226
+ elementType,
227
+ extraIncludes,
228
+ );
229
+ case 'ArrayTypeAnnotation':
230
+ return convertArrayTypeArray(
231
+ propertyName,
232
+ indexVariable,
233
+ loopLocalVariable,
234
+ propertyParts,
235
+ elementType,
236
+ extraIncludes,
237
+ usingEvent,
238
+ );
239
+ default:
240
+ throw new Error(
241
+ `Received invalid elementType for array ${elementType.type}`,
242
+ );
243
+ }
244
+ }
245
+
246
+ function convertObjectTypeArray(
247
+ propertyName: string,
248
+ indexVariable: string,
249
+ loopLocalVariable: string,
250
+ propertyParts: $ReadOnlyArray<string>,
251
+ objectTypeAnnotation: ObjectTypeAnnotation<EventTypeAnnotation>,
252
+ extraIncludes: Set<string>,
253
+ ): string {
254
+ return `auto ${propertyName}Object = jsi::Object(runtime);
255
+ ${generateSetters(
256
+ `${propertyName}Object`,
257
+ objectTypeAnnotation.properties,
258
+ [].concat([loopLocalVariable]),
259
+ extraIncludes,
260
+ false,
261
+ )}
262
+ ${setValueAtIndex(propertyName, indexVariable, `${propertyName}Object`)}`;
263
+ }
264
+
265
+ function convertArrayTypeArray(
266
+ propertyName: string,
267
+ indexVariable: string,
268
+ loopLocalVariable: string,
269
+ propertyParts: $ReadOnlyArray<string>,
270
+ eventTypeAnnotation: EventTypeAnnotation,
271
+ extraIncludes: Set<string>,
272
+ usingEvent: boolean,
273
+ ): string {
274
+ if (eventTypeAnnotation.type !== 'ArrayTypeAnnotation') {
275
+ throw new Error(
276
+ `Inconsistent eventTypeAnnotation received. Expected type = 'ArrayTypeAnnotation'; received = ${eventTypeAnnotation.type}`,
277
+ );
278
+ }
279
+ return `auto ${propertyName}Array = jsi::Array(runtime, ${loopLocalVariable}.size());
280
+ size_t ${indexVariable}Internal = 0;
281
+ for (auto ${loopLocalVariable}Internal : ${loopLocalVariable}) {
282
+ ${handleArrayElementType(
283
+ eventTypeAnnotation.elementType,
284
+ `${propertyName}Array`,
285
+ `${indexVariable}Internal`,
286
+ `${loopLocalVariable}Internal`,
287
+ propertyParts,
288
+ extraIncludes,
289
+ usingEvent,
290
+ )}
291
+ }
292
+ ${setValueAtIndex(propertyName, indexVariable, `${propertyName}Array`)}`;
293
+ }
294
+
142
295
  function generateSetters(
143
296
  parentPropertyName: string,
144
297
  properties: $ReadOnlyArray<NamedShape<EventTypeAnnotation>>,
145
298
  propertyParts: $ReadOnlyArray<string>,
299
+ extraIncludes: Set<string>,
300
+ usingEvent: boolean = true,
146
301
  ): string {
147
302
  const propSetters = properties
148
303
  .map(eventProperty => {
@@ -157,12 +312,24 @@ function generateSetters(
157
312
  parentPropertyName,
158
313
  eventProperty.name,
159
314
  propertyParts,
315
+ usingEvent,
316
+ );
317
+ case 'MixedTypeAnnotation':
318
+ extraIncludes.add('#include <jsi/JSIDynamic.h>');
319
+ return generateSetter(
320
+ parentPropertyName,
321
+ eventProperty.name,
322
+ propertyParts,
323
+ usingEvent,
324
+ prop => `jsi::valueFromDynamic(runtime, ${prop})`,
160
325
  );
161
326
  case 'StringEnumTypeAnnotation':
162
- return generateEnumSetter(
327
+ return generateSetter(
163
328
  parentPropertyName,
164
329
  eventProperty.name,
165
330
  propertyParts,
331
+ usingEvent,
332
+ prop => `toString(${prop})`,
166
333
  );
167
334
  case 'ObjectTypeAnnotation':
168
335
  return generateObjectSetter(
@@ -170,10 +337,23 @@ function generateSetters(
170
337
  eventProperty.name,
171
338
  propertyParts,
172
339
  typeAnnotation,
340
+ extraIncludes,
341
+ usingEvent,
342
+ );
343
+ case 'ArrayTypeAnnotation':
344
+ return generateArraySetter(
345
+ parentPropertyName,
346
+ eventProperty.name,
347
+ propertyParts,
348
+ typeAnnotation.elementType,
349
+ extraIncludes,
350
+ usingEvent,
173
351
  );
174
352
  default:
175
353
  (typeAnnotation.type: empty);
176
- throw new Error('Received invalid event property type');
354
+ throw new Error(
355
+ `Received invalid event property type ${typeAnnotation.type}`,
356
+ );
177
357
  }
178
358
  })
179
359
  .join('\n');
@@ -181,7 +361,11 @@ function generateSetters(
181
361
  return propSetters;
182
362
  }
183
363
 
184
- function generateEvent(componentName: string, event: EventTypeShape): string {
364
+ function generateEvent(
365
+ componentName: string,
366
+ event: EventTypeShape,
367
+ extraIncludes: Set<string>,
368
+ ): string {
185
369
  // This is a gross hack necessary because native code is sending
186
370
  // events named things like topChange to JS which is then converted back to
187
371
  // call the onChange prop. We should be consistent throughout the system.
@@ -195,7 +379,12 @@ function generateEvent(componentName: string, event: EventTypeShape): string {
195
379
  if (event.typeAnnotation.argument) {
196
380
  const implementation = `
197
381
  auto $payload = jsi::Object(runtime);
198
- ${generateSetters('$payload', event.typeAnnotation.argument.properties, [])}
382
+ ${generateSetters(
383
+ '$payload',
384
+ event.typeAnnotation.argument.properties,
385
+ [],
386
+ extraIncludes,
387
+ )}
199
388
  return $payload;
200
389
  `.trim();
201
390
 
@@ -244,23 +433,21 @@ module.exports = {
244
433
  .filter(Boolean)
245
434
  .reduce((acc, components) => Object.assign(acc, components), {});
246
435
 
247
- const fileName = 'EventEmitters.cpp';
248
-
436
+ const extraIncludes = new Set<string>();
249
437
  const componentEmitters = Object.keys(moduleComponents)
250
438
  .map(componentName => {
251
439
  const component = moduleComponents[componentName];
252
-
253
440
  return component.events
254
- .map(event => {
255
- return generateEvent(componentName, event);
256
- })
441
+ .map(event => generateEvent(componentName, event, extraIncludes))
257
442
  .join('\n');
258
443
  })
259
444
  .join('\n');
260
445
 
446
+ const fileName = 'EventEmitters.cpp';
261
447
  const replacedTemplate = FileTemplate({
262
448
  libraryName,
263
449
  events: componentEmitters,
450
+ extraIncludes,
264
451
  });
265
452
 
266
453
  return new Map([[fileName, replacedTemplate]]);