@react-native/codegen 0.72.5 → 0.73.0-nightly-20230603-fd9e295be

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 (72) 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/generators/components/CppHelpers.js +39 -2
  5. package/lib/generators/components/CppHelpers.js.flow +54 -5
  6. package/lib/generators/components/GenerateEventEmitterCpp.js +238 -55
  7. package/lib/generators/components/GenerateEventEmitterCpp.js.flow +233 -55
  8. package/lib/generators/components/GenerateEventEmitterH.js +77 -28
  9. package/lib/generators/components/GenerateEventEmitterH.js.flow +87 -32
  10. package/lib/generators/components/GeneratePropsH.js +1 -2
  11. package/lib/generators/components/GeneratePropsH.js.flow +1 -2
  12. package/lib/generators/components/GeneratePropsJavaPojo/PojoCollector.js +0 -1
  13. package/lib/generators/components/GeneratePropsJavaPojo/PojoCollector.js.flow +3 -5
  14. package/lib/generators/components/GenerateThirdPartyFabricComponentsProviderH.js +4 -0
  15. package/lib/generators/components/GenerateThirdPartyFabricComponentsProviderH.js.flow +4 -0
  16. package/lib/generators/components/GenerateThirdPartyFabricComponentsProviderObjCpp.js +2 -0
  17. package/lib/generators/components/GenerateThirdPartyFabricComponentsProviderObjCpp.js.flow +2 -0
  18. package/lib/generators/components/__test_fixtures__/fixtures.js +114 -1
  19. package/lib/generators/components/__test_fixtures__/fixtures.js.flow +114 -1
  20. package/lib/generators/modules/GenerateModuleCpp.js +3 -3
  21. package/lib/generators/modules/GenerateModuleCpp.js.flow +3 -3
  22. package/lib/generators/modules/GenerateModuleJavaSpec.js +1 -2
  23. package/lib/generators/modules/GenerateModuleJavaSpec.js.flow +1 -2
  24. package/lib/parsers/error-utils.js +44 -0
  25. package/lib/parsers/error-utils.js.flow +59 -0
  26. package/lib/parsers/flow/components/__test_fixtures__/fixtures.js +51 -0
  27. package/lib/parsers/flow/components/__test_fixtures__/fixtures.js.flow +51 -0
  28. package/lib/parsers/flow/components/componentsUtils.js +6 -6
  29. package/lib/parsers/flow/components/componentsUtils.js.flow +10 -10
  30. package/lib/parsers/flow/components/events.js +157 -78
  31. package/lib/parsers/flow/components/events.js.flow +158 -77
  32. package/lib/parsers/flow/components/index.js +28 -105
  33. package/lib/parsers/flow/components/index.js.flow +21 -110
  34. package/lib/parsers/flow/modules/index.js +39 -49
  35. package/lib/parsers/flow/modules/index.js.flow +22 -31
  36. package/lib/parsers/flow/parser.d.ts +9 -2
  37. package/lib/parsers/flow/parser.js +167 -16
  38. package/lib/parsers/flow/parser.js.flow +209 -6
  39. package/lib/parsers/flow/utils.js +0 -63
  40. package/lib/parsers/flow/utils.js.flow +1 -77
  41. package/lib/parsers/parser.js.flow +141 -1
  42. package/lib/parsers/parserMock.js +165 -2
  43. package/lib/parsers/parserMock.js.flow +216 -2
  44. package/lib/parsers/parsers-commons.js +128 -9
  45. package/lib/parsers/parsers-commons.js.flow +182 -12
  46. package/lib/parsers/parsers-primitives.js +84 -35
  47. package/lib/parsers/parsers-primitives.js.flow +110 -35
  48. package/lib/parsers/typescript/components/__test_fixtures__/fixtures.js +51 -0
  49. package/lib/parsers/typescript/components/__test_fixtures__/fixtures.js.flow +51 -0
  50. package/lib/parsers/typescript/components/componentsUtils.js +31 -7
  51. package/lib/parsers/typescript/components/componentsUtils.js.flow +31 -14
  52. package/lib/parsers/typescript/components/events.js +142 -67
  53. package/lib/parsers/typescript/components/events.js.flow +149 -68
  54. package/lib/parsers/typescript/components/extends.js +2 -49
  55. package/lib/parsers/typescript/components/extends.js.flow +1 -55
  56. package/lib/parsers/typescript/components/index.js +29 -109
  57. package/lib/parsers/typescript/components/index.js.flow +21 -116
  58. package/lib/parsers/typescript/modules/index.js +41 -50
  59. package/lib/parsers/typescript/modules/index.js.flow +23 -31
  60. package/lib/parsers/typescript/parser.d.ts +9 -2
  61. package/lib/parsers/typescript/parser.js +193 -7
  62. package/lib/parsers/typescript/parser.js.flow +235 -6
  63. package/lib/parsers/utils.js.flow +6 -0
  64. package/package.json +16 -5
  65. package/lib/parsers/flow/components/extends.js +0 -52
  66. package/lib/parsers/flow/components/extends.js.flow +0 -66
  67. package/lib/parsers/flow/components/props.js +0 -47
  68. package/lib/parsers/flow/components/props.js.flow +0 -60
  69. package/lib/parsers/typescript/components/props.js +0 -39
  70. package/lib/parsers/typescript/components/props.js.flow +0 -48
  71. package/lib/parsers/typescript/utils.js +0 -90
  72. package/lib/parsers/typescript/utils.js.flow +0 -104
@@ -11,13 +11,15 @@
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,
18
19
  NamedShape,
19
20
  EventTypeAnnotation,
20
21
  SchemaType,
22
+ ObjectTypeAnnotation,
21
23
  } from '../../CodegenSchema';
22
24
 
23
25
  // File path -> contents
@@ -31,9 +33,11 @@ type ComponentCollection = $ReadOnly<{
31
33
  const FileTemplate = ({
32
34
  events,
33
35
  libraryName,
36
+ extraIncludes,
34
37
  }: {
35
38
  events: string,
36
39
  libraryName: string,
40
+ extraIncludes: Set<string>,
37
41
  }) => `
38
42
  /**
39
43
  * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
@@ -45,12 +49,11 @@ const FileTemplate = ({
45
49
  */
46
50
 
47
51
  #include <react/renderer/components/${libraryName}/EventEmitters.h>
52
+ ${[...extraIncludes].join('\n')}
48
53
 
49
54
  namespace facebook {
50
55
  namespace react {
51
-
52
56
  ${events}
53
-
54
57
  } // namespace react
55
58
  } // namespace facebook
56
59
  `;
@@ -68,16 +71,16 @@ const ComponentTemplate = ({
68
71
  dispatchEventName: string,
69
72
  implementation: string,
70
73
  }) => {
71
- const capture = implementation.includes('event')
72
- ? 'event=std::move(event)'
74
+ const capture = implementation.includes('$event')
75
+ ? '$event=std::move($event)'
73
76
  : '';
74
77
  return `
75
- void ${className}EventEmitter::${eventName}(${structName} event) const {
78
+ void ${className}EventEmitter::${eventName}(${structName} $event) const {
76
79
  dispatchEvent("${dispatchEventName}", [${capture}](jsi::Runtime &runtime) {
77
80
  ${implementation}
78
81
  });
79
82
  }
80
- `.trim();
83
+ `;
81
84
  };
82
85
 
83
86
  const BasicComponentTemplate = ({
@@ -99,90 +102,258 @@ function generateSetter(
99
102
  variableName: string,
100
103
  propertyName: string,
101
104
  propertyParts: $ReadOnlyArray<string>,
105
+ usingEvent: boolean,
106
+ valueMapper: string => string = value => value,
102
107
  ) {
103
- const trailingPeriod = propertyParts.length === 0 ? '' : '.';
104
- const eventChain = `event.${propertyParts.join(
105
- '.',
106
- )}${trailingPeriod}${propertyName});`;
107
-
108
- return `${variableName}.setProperty(runtime, "${propertyName}", ${eventChain}`;
108
+ const eventChain = usingEvent
109
+ ? `$event.${[...propertyParts, propertyName].join('.')}`
110
+ : [propertyParts, propertyName].join('.');
111
+ return `${variableName}.setProperty(runtime, "${propertyName}", ${valueMapper(
112
+ eventChain,
113
+ )});`;
109
114
  }
110
115
 
111
- function generateEnumSetter(
116
+ function generateObjectSetter(
112
117
  variableName: string,
113
118
  propertyName: string,
114
119
  propertyParts: $ReadOnlyArray<string>,
120
+ typeAnnotation: ObjectTypeAnnotation<EventTypeAnnotation>,
121
+ extraIncludes: Set<string>,
122
+ usingEvent: boolean,
115
123
  ) {
116
- const trailingPeriod = propertyParts.length === 0 ? '' : '.';
117
- const eventChain = `event.${propertyParts.join(
118
- '.',
119
- )}${trailingPeriod}${propertyName})`;
124
+ return `
125
+ {
126
+ auto ${propertyName} = jsi::Object(runtime);
127
+ ${indent(
128
+ generateSetters(
129
+ propertyName,
130
+ typeAnnotation.properties,
131
+ propertyParts.concat([propertyName]),
132
+ extraIncludes,
133
+ usingEvent,
134
+ ),
135
+ 2,
136
+ )}
137
+ ${variableName}.setProperty(runtime, "${propertyName}", ${propertyName});
138
+ }
139
+ `.trim();
140
+ }
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
+ }
120
264
 
121
- return `${variableName}.setProperty(runtime, "${propertyName}", toString(${eventChain});`;
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`)}`;
122
293
  }
123
294
 
124
295
  function generateSetters(
125
296
  parentPropertyName: string,
126
297
  properties: $ReadOnlyArray<NamedShape<EventTypeAnnotation>>,
127
298
  propertyParts: $ReadOnlyArray<string>,
299
+ extraIncludes: Set<string>,
300
+ usingEvent: boolean = true,
128
301
  ): string {
129
302
  const propSetters = properties
130
303
  .map(eventProperty => {
131
304
  const {typeAnnotation} = eventProperty;
132
305
  switch (typeAnnotation.type) {
133
306
  case 'BooleanTypeAnnotation':
134
- return generateSetter(
135
- parentPropertyName,
136
- eventProperty.name,
137
- propertyParts,
138
- );
139
307
  case 'StringTypeAnnotation':
308
+ case 'Int32TypeAnnotation':
309
+ case 'DoubleTypeAnnotation':
310
+ case 'FloatTypeAnnotation':
140
311
  return generateSetter(
141
312
  parentPropertyName,
142
313
  eventProperty.name,
143
314
  propertyParts,
315
+ usingEvent,
144
316
  );
145
- case 'Int32TypeAnnotation':
317
+ case 'MixedTypeAnnotation':
318
+ extraIncludes.add('#include <jsi/JSIDynamic.h>');
146
319
  return generateSetter(
147
320
  parentPropertyName,
148
321
  eventProperty.name,
149
322
  propertyParts,
323
+ usingEvent,
324
+ prop => `jsi::valueFromDynamic(runtime, ${prop})`,
150
325
  );
151
- case 'DoubleTypeAnnotation':
326
+ case 'StringEnumTypeAnnotation':
152
327
  return generateSetter(
153
328
  parentPropertyName,
154
329
  eventProperty.name,
155
330
  propertyParts,
331
+ usingEvent,
332
+ prop => `toString(${prop})`,
156
333
  );
157
- case 'FloatTypeAnnotation':
158
- return generateSetter(
334
+ case 'ObjectTypeAnnotation':
335
+ return generateObjectSetter(
159
336
  parentPropertyName,
160
337
  eventProperty.name,
161
338
  propertyParts,
339
+ typeAnnotation,
340
+ extraIncludes,
341
+ usingEvent,
162
342
  );
163
- case 'StringEnumTypeAnnotation':
164
- return generateEnumSetter(
343
+ case 'ArrayTypeAnnotation':
344
+ return generateArraySetter(
165
345
  parentPropertyName,
166
346
  eventProperty.name,
167
347
  propertyParts,
348
+ typeAnnotation.elementType,
349
+ extraIncludes,
350
+ usingEvent,
168
351
  );
169
- case 'ObjectTypeAnnotation':
170
- const propertyName = eventProperty.name;
171
- return `
172
- {
173
- auto ${propertyName} = jsi::Object(runtime);
174
- ${generateSetters(
175
- propertyName,
176
- typeAnnotation.properties,
177
- propertyParts.concat([propertyName]),
178
- )}
179
-
180
- ${parentPropertyName}.setProperty(runtime, "${propertyName}", ${propertyName});
181
- }
182
- `.trim();
183
352
  default:
184
353
  (typeAnnotation.type: empty);
185
- throw new Error('Received invalid event property type');
354
+ throw new Error(
355
+ `Received invalid event property type ${typeAnnotation.type}`,
356
+ );
186
357
  }
187
358
  })
188
359
  .join('\n');
@@ -190,7 +361,11 @@ function generateSetters(
190
361
  return propSetters;
191
362
  }
192
363
 
193
- function generateEvent(componentName: string, event: EventTypeShape): string {
364
+ function generateEvent(
365
+ componentName: string,
366
+ event: EventTypeShape,
367
+ extraIncludes: Set<string>,
368
+ ): string {
194
369
  // This is a gross hack necessary because native code is sending
195
370
  // events named things like topChange to JS which is then converted back to
196
371
  // call the onChange prop. We should be consistent throughout the system.
@@ -203,9 +378,14 @@ function generateEvent(componentName: string, event: EventTypeShape): string {
203
378
 
204
379
  if (event.typeAnnotation.argument) {
205
380
  const implementation = `
206
- auto payload = jsi::Object(runtime);
207
- ${generateSetters('payload', event.typeAnnotation.argument.properties, [])}
208
- return payload;
381
+ auto $payload = jsi::Object(runtime);
382
+ ${generateSetters(
383
+ '$payload',
384
+ event.typeAnnotation.argument.properties,
385
+ [],
386
+ extraIncludes,
387
+ )}
388
+ return $payload;
209
389
  `.trim();
210
390
 
211
391
  if (!event.name.startsWith('on')) {
@@ -253,23 +433,21 @@ module.exports = {
253
433
  .filter(Boolean)
254
434
  .reduce((acc, components) => Object.assign(acc, components), {});
255
435
 
256
- const fileName = 'EventEmitters.cpp';
257
-
436
+ const extraIncludes = new Set<string>();
258
437
  const componentEmitters = Object.keys(moduleComponents)
259
438
  .map(componentName => {
260
439
  const component = moduleComponents[componentName];
261
-
262
440
  return component.events
263
- .map(event => {
264
- return generateEvent(componentName, event);
265
- })
441
+ .map(event => generateEvent(componentName, event, extraIncludes))
266
442
  .join('\n');
267
443
  })
268
444
  .join('\n');
269
445
 
446
+ const fileName = 'EventEmitters.cpp';
270
447
  const replacedTemplate = FileTemplate({
271
448
  libraryName,
272
449
  events: componentEmitters,
450
+ extraIncludes,
273
451
  });
274
452
 
275
453
  return new Map([[fileName, replacedTemplate]]);
@@ -12,12 +12,14 @@
12
12
 
13
13
  const nullthrows = require('nullthrows');
14
14
  const _require = require('./CppHelpers'),
15
+ getImports = _require.getImports,
16
+ getCppArrayTypeForAnnotation = _require.getCppArrayTypeForAnnotation,
15
17
  getCppTypeForAnnotation = _require.getCppTypeForAnnotation,
16
18
  generateEventStructName = _require.generateEventStructName;
17
19
  const _require2 = require('../Utils'),
18
20
  indent = _require2.indent,
19
21
  toSafeCppString = _require2.toSafeCppString;
20
- const FileTemplate = ({componentEmitters}) => `
22
+ const FileTemplate = ({componentEmitters, extraIncludes}) => `
21
23
  /**
22
24
  * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
23
25
  *
@@ -29,24 +31,21 @@ const FileTemplate = ({componentEmitters}) => `
29
31
  #pragma once
30
32
 
31
33
  #include <react/renderer/components/view/ViewEventEmitter.h>
32
- #include <jsi/jsi.h>
34
+ ${[...extraIncludes].join('\n')}
33
35
 
34
36
  namespace facebook {
35
37
  namespace react {
36
-
37
38
  ${componentEmitters}
38
-
39
39
  } // namespace react
40
40
  } // namespace facebook
41
41
  `;
42
42
  const ComponentTemplate = ({className, structs, events}) =>
43
43
  `
44
- class JSI_EXPORT ${className}EventEmitter : public ViewEventEmitter {
44
+ class ${className}EventEmitter : public ViewEventEmitter {
45
45
  public:
46
46
  using ViewEventEmitter::ViewEventEmitter;
47
47
 
48
48
  ${structs}
49
-
50
49
  ${events}
51
50
  };
52
51
  `.trim();
@@ -75,11 +74,22 @@ function getNativeTypeFromAnnotation(componentName, eventProperty, nameParts) {
75
74
  case 'Int32TypeAnnotation':
76
75
  case 'DoubleTypeAnnotation':
77
76
  case 'FloatTypeAnnotation':
77
+ case 'MixedTypeAnnotation':
78
78
  return getCppTypeForAnnotation(type);
79
79
  case 'StringEnumTypeAnnotation':
80
- return generateEventStructName(nameParts.concat([eventProperty.name]));
81
80
  case 'ObjectTypeAnnotation':
82
- return generateEventStructName(nameParts.concat([eventProperty.name]));
81
+ return generateEventStructName([...nameParts, eventProperty.name]);
82
+ case 'ArrayTypeAnnotation':
83
+ const eventTypeAnnotation = eventProperty.typeAnnotation;
84
+ if (eventTypeAnnotation.type !== 'ArrayTypeAnnotation') {
85
+ throw new Error(
86
+ "Inconsistent Codegen state: type was ArrayTypeAnnotation at the beginning of the body and now it isn't",
87
+ );
88
+ }
89
+ return getCppArrayTypeForAnnotation(eventTypeAnnotation.elementType, [
90
+ ...nameParts,
91
+ eventProperty.name,
92
+ ]);
83
93
  default:
84
94
  type;
85
95
  throw new Error(`Received invalid event property type ${type}`);
@@ -105,6 +115,32 @@ function generateEnum(structs, options, nameParts) {
105
115
  }),
106
116
  );
107
117
  }
118
+ function handleGenerateStructForArray(
119
+ structs,
120
+ name,
121
+ componentName,
122
+ elementType,
123
+ nameParts,
124
+ ) {
125
+ if (elementType.type === 'ObjectTypeAnnotation') {
126
+ generateStruct(
127
+ structs,
128
+ componentName,
129
+ nameParts.concat([name]),
130
+ nullthrows(elementType.properties),
131
+ );
132
+ } else if (elementType.type === 'StringEnumTypeAnnotation') {
133
+ generateEnum(structs, elementType.options, nameParts.concat([name]));
134
+ } else if (elementType.type === 'ArrayTypeAnnotation') {
135
+ handleGenerateStructForArray(
136
+ structs,
137
+ name,
138
+ componentName,
139
+ elementType.elementType,
140
+ nameParts,
141
+ );
142
+ }
143
+ }
108
144
  function generateStruct(structs, componentName, nameParts, properties) {
109
145
  const structNameParts = nameParts;
110
146
  const structName = generateEventStructName(structNameParts);
@@ -122,14 +158,20 @@ function generateStruct(structs, componentName, nameParts, properties) {
122
158
  typeAnnotation = property.typeAnnotation;
123
159
  switch (typeAnnotation.type) {
124
160
  case 'BooleanTypeAnnotation':
125
- return;
126
161
  case 'StringTypeAnnotation':
127
- return;
128
162
  case 'Int32TypeAnnotation':
129
- return;
130
163
  case 'DoubleTypeAnnotation':
131
- return;
132
164
  case 'FloatTypeAnnotation':
165
+ case 'MixedTypeAnnotation':
166
+ return;
167
+ case 'ArrayTypeAnnotation':
168
+ handleGenerateStructForArray(
169
+ structs,
170
+ name,
171
+ componentName,
172
+ typeAnnotation.elementType,
173
+ nameParts,
174
+ );
133
175
  return;
134
176
  case 'ObjectTypeAnnotation':
135
177
  generateStruct(
@@ -189,7 +231,7 @@ module.exports = {
189
231
  .map(moduleName => {
190
232
  const module = schema.modules[moduleName];
191
233
  if (module.type !== 'Component') {
192
- return;
234
+ return null;
193
235
  }
194
236
  const components = module.components;
195
237
  // No components in this module
@@ -200,24 +242,31 @@ module.exports = {
200
242
  })
201
243
  .filter(Boolean)
202
244
  .reduce((acc, components) => Object.assign(acc, components), {});
203
- const moduleComponentsWithEvents = Object.keys(moduleComponents);
245
+ const extraIncludes = new Set();
246
+ const componentEmitters = Object.keys(moduleComponents)
247
+ .map(componentName => {
248
+ const component = moduleComponents[componentName];
249
+ component.events.forEach(event => {
250
+ if (event.typeAnnotation.argument) {
251
+ const argIncludes = getImports(
252
+ event.typeAnnotation.argument.properties,
253
+ );
254
+ // $FlowFixMe[method-unbinding]
255
+ argIncludes.forEach(extraIncludes.add, extraIncludes);
256
+ }
257
+ });
258
+ const replacedTemplate = ComponentTemplate({
259
+ className: componentName,
260
+ structs: indent(generateStructs(componentName, component), 2),
261
+ events: generateEvents(componentName, component),
262
+ });
263
+ return replacedTemplate;
264
+ })
265
+ .join('\n');
204
266
  const fileName = 'EventEmitters.h';
205
- const componentEmitters =
206
- moduleComponentsWithEvents.length > 0
207
- ? Object.keys(moduleComponents)
208
- .map(componentName => {
209
- const component = moduleComponents[componentName];
210
- const replacedTemplate = ComponentTemplate({
211
- className: componentName,
212
- structs: indent(generateStructs(componentName, component), 2),
213
- events: generateEvents(componentName, component),
214
- });
215
- return replacedTemplate;
216
- })
217
- .join('\n')
218
- : '';
219
267
  const replacedTemplate = FileTemplate({
220
268
  componentEmitters,
269
+ extraIncludes,
221
270
  });
222
271
  return new Map([[fileName, replacedTemplate]]);
223
272
  },