@react-native/codegen 0.72.4 → 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 (74) 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/GenerateModuleH.js +1 -1
  23. package/lib/generators/modules/GenerateModuleH.js.flow +1 -1
  24. package/lib/generators/modules/GenerateModuleJavaSpec.js +1 -2
  25. package/lib/generators/modules/GenerateModuleJavaSpec.js.flow +1 -2
  26. package/lib/parsers/error-utils.js +44 -0
  27. package/lib/parsers/error-utils.js.flow +59 -0
  28. package/lib/parsers/flow/components/__test_fixtures__/fixtures.js +51 -0
  29. package/lib/parsers/flow/components/__test_fixtures__/fixtures.js.flow +51 -0
  30. package/lib/parsers/flow/components/componentsUtils.js +6 -6
  31. package/lib/parsers/flow/components/componentsUtils.js.flow +10 -10
  32. package/lib/parsers/flow/components/events.js +157 -78
  33. package/lib/parsers/flow/components/events.js.flow +158 -77
  34. package/lib/parsers/flow/components/index.js +28 -105
  35. package/lib/parsers/flow/components/index.js.flow +21 -110
  36. package/lib/parsers/flow/modules/index.js +39 -49
  37. package/lib/parsers/flow/modules/index.js.flow +22 -31
  38. package/lib/parsers/flow/parser.d.ts +9 -2
  39. package/lib/parsers/flow/parser.js +167 -16
  40. package/lib/parsers/flow/parser.js.flow +209 -6
  41. package/lib/parsers/flow/utils.js +0 -63
  42. package/lib/parsers/flow/utils.js.flow +1 -77
  43. package/lib/parsers/parser.js.flow +141 -1
  44. package/lib/parsers/parserMock.js +165 -2
  45. package/lib/parsers/parserMock.js.flow +216 -2
  46. package/lib/parsers/parsers-commons.js +128 -9
  47. package/lib/parsers/parsers-commons.js.flow +182 -12
  48. package/lib/parsers/parsers-primitives.js +84 -35
  49. package/lib/parsers/parsers-primitives.js.flow +110 -35
  50. package/lib/parsers/typescript/components/__test_fixtures__/fixtures.js +51 -0
  51. package/lib/parsers/typescript/components/__test_fixtures__/fixtures.js.flow +51 -0
  52. package/lib/parsers/typescript/components/componentsUtils.js +31 -7
  53. package/lib/parsers/typescript/components/componentsUtils.js.flow +31 -14
  54. package/lib/parsers/typescript/components/events.js +142 -67
  55. package/lib/parsers/typescript/components/events.js.flow +149 -68
  56. package/lib/parsers/typescript/components/extends.js +2 -49
  57. package/lib/parsers/typescript/components/extends.js.flow +1 -55
  58. package/lib/parsers/typescript/components/index.js +29 -109
  59. package/lib/parsers/typescript/components/index.js.flow +21 -116
  60. package/lib/parsers/typescript/modules/index.js +41 -50
  61. package/lib/parsers/typescript/modules/index.js.flow +23 -31
  62. package/lib/parsers/typescript/parser.d.ts +9 -2
  63. package/lib/parsers/typescript/parser.js +193 -7
  64. package/lib/parsers/typescript/parser.js.flow +235 -6
  65. package/lib/parsers/utils.js.flow +6 -0
  66. package/package.json +26 -15
  67. package/lib/parsers/flow/components/extends.js +0 -52
  68. package/lib/parsers/flow/components/extends.js.flow +0 -66
  69. package/lib/parsers/flow/components/props.js +0 -47
  70. package/lib/parsers/flow/components/props.js.flow +0 -60
  71. package/lib/parsers/typescript/components/props.js +0 -39
  72. package/lib/parsers/typescript/components/props.js.flow +0 -48
  73. package/lib/parsers/typescript/utils.js +0 -90
  74. package/lib/parsers/typescript/utils.js.flow +0 -104
@@ -10,34 +10,31 @@
10
10
 
11
11
  'use strict';
12
12
 
13
+ const _require = require('../../error-utils'),
14
+ throwIfEventHasNoName = _require.throwIfEventHasNoName,
15
+ throwIfBubblingTypeIsNull = _require.throwIfBubblingTypeIsNull,
16
+ throwIfArgumentPropsAreNull = _require.throwIfArgumentPropsAreNull;
17
+ const _require2 = require('../../parsers-commons'),
18
+ getEventArgument = _require2.getEventArgument;
19
+ const _require3 = require('../../parsers-primitives'),
20
+ emitBoolProp = _require3.emitBoolProp,
21
+ emitDoubleProp = _require3.emitDoubleProp,
22
+ emitFloatProp = _require3.emitFloatProp,
23
+ emitStringProp = _require3.emitStringProp;
13
24
  function getPropertyType(
14
25
  /* $FlowFixMe[missing-local-annot] The type annotation(s) required by Flow's
15
26
  * LTI update could not be added via codemod */
16
27
  name,
17
28
  optional,
18
29
  typeAnnotation,
30
+ parser,
19
31
  ) {
20
- const type =
21
- typeAnnotation.type === 'GenericTypeAnnotation'
22
- ? typeAnnotation.id.name
23
- : typeAnnotation.type;
32
+ const type = extractTypeFromTypeAnnotation(typeAnnotation);
24
33
  switch (type) {
25
34
  case 'BooleanTypeAnnotation':
26
- return {
27
- name,
28
- optional,
29
- typeAnnotation: {
30
- type: 'BooleanTypeAnnotation',
31
- },
32
- };
35
+ return emitBoolProp(name, optional);
33
36
  case 'StringTypeAnnotation':
34
- return {
35
- name,
36
- optional,
37
- typeAnnotation: {
38
- type: 'StringTypeAnnotation',
39
- },
40
- };
37
+ return emitStringProp(name, optional);
41
38
  case 'Int32':
42
39
  return {
43
40
  name,
@@ -47,26 +44,15 @@ function getPropertyType(
47
44
  },
48
45
  };
49
46
  case 'Double':
50
- return {
51
- name,
52
- optional,
53
- typeAnnotation: {
54
- type: 'DoubleTypeAnnotation',
55
- },
56
- };
47
+ return emitDoubleProp(name, optional);
57
48
  case 'Float':
58
- return {
59
- name,
60
- optional,
61
- typeAnnotation: {
62
- type: 'FloatTypeAnnotation',
63
- },
64
- };
49
+ return emitFloatProp(name, optional);
65
50
  case '$ReadOnly':
66
51
  return getPropertyType(
67
52
  name,
68
53
  optional,
69
54
  typeAnnotation.typeParameters.params[0],
55
+ parser,
70
56
  );
71
57
  case 'ObjectTypeAnnotation':
72
58
  return {
@@ -74,7 +60,9 @@ function getPropertyType(
74
60
  optional,
75
61
  typeAnnotation: {
76
62
  type: 'ObjectTypeAnnotation',
77
- properties: typeAnnotation.properties.map(buildPropertiesForEvent),
63
+ properties: typeAnnotation.properties.map(member =>
64
+ buildPropertiesForEvent(member, parser),
65
+ ),
78
66
  },
79
67
  };
80
68
  case 'UnionTypeAnnotation':
@@ -86,20 +74,111 @@ function getPropertyType(
86
74
  options: typeAnnotation.types.map(option => option.value),
87
75
  },
88
76
  };
77
+ case 'UnsafeMixed':
78
+ return {
79
+ name,
80
+ optional,
81
+ typeAnnotation: {
82
+ type: 'MixedTypeAnnotation',
83
+ },
84
+ };
85
+ case 'ArrayTypeAnnotation':
86
+ case '$ReadOnlyArray':
87
+ return {
88
+ name,
89
+ optional,
90
+ typeAnnotation: extractArrayElementType(typeAnnotation, name, parser),
91
+ };
89
92
  default:
90
- type;
91
93
  throw new Error(`Unable to determine event type for "${name}": ${type}`);
92
94
  }
93
95
  }
96
+ function extractArrayElementType(typeAnnotation, name, parser) {
97
+ const type = extractTypeFromTypeAnnotation(typeAnnotation);
98
+ switch (type) {
99
+ case 'BooleanTypeAnnotation':
100
+ return {
101
+ type: 'BooleanTypeAnnotation',
102
+ };
103
+ case 'StringTypeAnnotation':
104
+ return {
105
+ type: 'StringTypeAnnotation',
106
+ };
107
+ case 'Int32':
108
+ return {
109
+ type: 'Int32TypeAnnotation',
110
+ };
111
+ case 'Float':
112
+ return {
113
+ type: 'FloatTypeAnnotation',
114
+ };
115
+ case 'NumberTypeAnnotation':
116
+ case 'Double':
117
+ return {
118
+ type: 'DoubleTypeAnnotation',
119
+ };
120
+ case 'UnionTypeAnnotation':
121
+ return {
122
+ type: 'StringEnumTypeAnnotation',
123
+ options: typeAnnotation.types.map(option => option.value),
124
+ };
125
+ case 'UnsafeMixed':
126
+ return {
127
+ type: 'MixedTypeAnnotation',
128
+ };
129
+ case 'ObjectTypeAnnotation':
130
+ return {
131
+ type: 'ObjectTypeAnnotation',
132
+ properties: typeAnnotation.properties.map(member =>
133
+ buildPropertiesForEvent(member, parser),
134
+ ),
135
+ };
136
+ case 'ArrayTypeAnnotation':
137
+ return {
138
+ type: 'ArrayTypeAnnotation',
139
+ elementType: extractArrayElementType(
140
+ typeAnnotation.elementType,
141
+ name,
142
+ parser,
143
+ ),
144
+ };
145
+ case '$ReadOnlyArray':
146
+ const genericParams = typeAnnotation.typeParameters.params;
147
+ if (genericParams.length !== 1) {
148
+ throw new Error(
149
+ `Events only supports arrays with 1 Generic type. Found ${
150
+ genericParams.length
151
+ } types:\n${prettify(genericParams)}`,
152
+ );
153
+ }
154
+ return {
155
+ type: 'ArrayTypeAnnotation',
156
+ elementType: extractArrayElementType(genericParams[0], name, parser),
157
+ };
158
+ default:
159
+ throw new Error(
160
+ `Unrecognized ${type} for Array ${name} in events.\n${prettify(
161
+ typeAnnotation,
162
+ )}`,
163
+ );
164
+ }
165
+ }
166
+ function prettify(jsonObject) {
167
+ return JSON.stringify(jsonObject, null, 2);
168
+ }
169
+ function extractTypeFromTypeAnnotation(typeAnnotation) {
170
+ return typeAnnotation.type === 'GenericTypeAnnotation'
171
+ ? typeAnnotation.id.name
172
+ : typeAnnotation.type;
173
+ }
94
174
  function findEventArgumentsAndType(
175
+ parser,
95
176
  typeAnnotation,
96
177
  types,
97
178
  bubblingType,
98
179
  paperName,
99
180
  ) {
100
- if (!typeAnnotation.id) {
101
- throw new Error("typeAnnotation of event doesn't have a name");
102
- }
181
+ throwIfEventHasNoName(typeAnnotation, parser);
103
182
  const name = typeAnnotation.id.name;
104
183
  if (name === '$ReadOnly') {
105
184
  return {
@@ -115,7 +194,7 @@ function findEventArgumentsAndType(
115
194
  : null;
116
195
  if (
117
196
  typeAnnotation.typeParameters.params[0].type ===
118
- 'NullLiteralTypeAnnotation'
197
+ parser.nullLiteralTypeAnnotation
119
198
  ) {
120
199
  return {
121
200
  argumentProps: [],
@@ -124,6 +203,7 @@ function findEventArgumentsAndType(
124
203
  };
125
204
  }
126
205
  return findEventArgumentsAndType(
206
+ parser,
127
207
  typeAnnotation.typeParameters.params[0],
128
208
  types,
129
209
  eventType,
@@ -131,6 +211,7 @@ function findEventArgumentsAndType(
131
211
  );
132
212
  } else if (types[name]) {
133
213
  return findEventArgumentsAndType(
214
+ parser,
134
215
  types[name].right,
135
216
  types,
136
217
  bubblingType,
@@ -144,29 +225,21 @@ function findEventArgumentsAndType(
144
225
  };
145
226
  }
146
227
  }
147
-
148
- /* $FlowFixMe[missing-local-annot] The type annotation(s) required by Flow's
149
- * LTI update could not be added via codemod */
150
- function buildPropertiesForEvent(property) {
228
+ function buildPropertiesForEvent(
229
+ /* $FlowFixMe[missing-local-annot] The type annotation(s) required by Flow's
230
+ * LTI update could not be added via codemod */
231
+ property,
232
+ parser,
233
+ ) {
151
234
  const name = property.key.name;
152
- const optional =
153
- property.value.type === 'NullableTypeAnnotation' || property.optional;
235
+ const optional = parser.isOptionalProperty(property);
154
236
  let typeAnnotation =
155
237
  property.value.type === 'NullableTypeAnnotation'
156
238
  ? property.value.typeAnnotation
157
239
  : property.value;
158
- return getPropertyType(name, optional, typeAnnotation);
159
- }
160
-
161
- /* $FlowFixMe[missing-local-annot] The type annotation(s) required by Flow's
162
- * LTI update could not be added via codemod */
163
- function getEventArgument(argumentProps, name) {
164
- return {
165
- type: 'ObjectTypeAnnotation',
166
- properties: argumentProps.map(buildPropertiesForEvent),
167
- };
240
+ return getPropertyType(name, optional, typeAnnotation, parser);
168
241
  }
169
- function buildEventSchema(types, property) {
242
+ function buildEventSchema(types, property, parser) {
170
243
  const name = property.key.name;
171
244
  const optional =
172
245
  property.optional || property.value.type === 'NullableTypeAnnotation';
@@ -182,6 +255,7 @@ function buildEventSchema(types, property) {
182
255
  return null;
183
256
  }
184
257
  const _findEventArgumentsAn = findEventArgumentsAndType(
258
+ parser,
185
259
  typeAnnotation,
186
260
  types,
187
261
  ),
@@ -189,43 +263,48 @@ function buildEventSchema(types, property) {
189
263
  bubblingType = _findEventArgumentsAn.bubblingType,
190
264
  paperTopLevelNameDeprecated =
191
265
  _findEventArgumentsAn.paperTopLevelNameDeprecated;
192
- if (bubblingType && argumentProps) {
193
- if (paperTopLevelNameDeprecated != null) {
194
- return {
195
- name,
196
- optional,
197
- bubblingType,
198
- paperTopLevelNameDeprecated,
199
- typeAnnotation: {
200
- type: 'EventTypeAnnotation',
201
- argument: getEventArgument(argumentProps, name),
202
- },
203
- };
204
- }
266
+ const nonNullableArgumentProps = throwIfArgumentPropsAreNull(
267
+ argumentProps,
268
+ name,
269
+ );
270
+ const nonNullableBubblingType = throwIfBubblingTypeIsNull(bubblingType, name);
271
+ if (paperTopLevelNameDeprecated != null) {
205
272
  return {
206
273
  name,
207
274
  optional,
208
- bubblingType,
275
+ bubblingType: nonNullableBubblingType,
276
+ paperTopLevelNameDeprecated,
209
277
  typeAnnotation: {
210
278
  type: 'EventTypeAnnotation',
211
- argument: getEventArgument(argumentProps, name),
279
+ argument: getEventArgument(
280
+ nonNullableArgumentProps,
281
+ buildPropertiesForEvent,
282
+ parser,
283
+ ),
212
284
  },
213
285
  };
214
286
  }
215
- if (argumentProps === null) {
216
- throw new Error(`Unable to determine event arguments for "${name}"`);
217
- }
218
- if (bubblingType === null) {
219
- throw new Error(`Unable to determine event arguments for "${name}"`);
220
- }
287
+ return {
288
+ name,
289
+ optional,
290
+ bubblingType: nonNullableBubblingType,
291
+ typeAnnotation: {
292
+ type: 'EventTypeAnnotation',
293
+ argument: getEventArgument(
294
+ nonNullableArgumentProps,
295
+ buildPropertiesForEvent,
296
+ parser,
297
+ ),
298
+ },
299
+ };
221
300
  }
222
301
 
223
302
  // $FlowFixMe[unclear-type] there's no flowtype for ASTs
224
303
 
225
- function getEvents(eventTypeAST, types) {
304
+ function getEvents(eventTypeAST, types, parser) {
226
305
  return eventTypeAST
227
306
  .filter(property => property.type === 'ObjectTypeProperty')
228
- .map(property => buildEventSchema(types, property))
307
+ .map(property => buildEventSchema(types, property, parser))
229
308
  .filter(Boolean);
230
309
  }
231
310
  module.exports = {
@@ -15,6 +15,20 @@ import type {
15
15
  NamedShape,
16
16
  EventTypeAnnotation,
17
17
  } from '../../../CodegenSchema.js';
18
+ import type {Parser} from '../../parser';
19
+
20
+ const {
21
+ throwIfEventHasNoName,
22
+ throwIfBubblingTypeIsNull,
23
+ throwIfArgumentPropsAreNull,
24
+ } = require('../../error-utils');
25
+ const {getEventArgument} = require('../../parsers-commons');
26
+ const {
27
+ emitBoolProp,
28
+ emitDoubleProp,
29
+ emitFloatProp,
30
+ emitStringProp,
31
+ } = require('../../parsers-primitives');
18
32
 
19
33
  function getPropertyType(
20
34
  /* $FlowFixMe[missing-local-annot] The type annotation(s) required by Flow's
@@ -22,29 +36,15 @@ function getPropertyType(
22
36
  name,
23
37
  optional: boolean,
24
38
  typeAnnotation: $FlowFixMe,
39
+ parser: Parser,
25
40
  ): NamedShape<EventTypeAnnotation> {
26
- const type =
27
- typeAnnotation.type === 'GenericTypeAnnotation'
28
- ? typeAnnotation.id.name
29
- : typeAnnotation.type;
41
+ const type = extractTypeFromTypeAnnotation(typeAnnotation);
30
42
 
31
43
  switch (type) {
32
44
  case 'BooleanTypeAnnotation':
33
- return {
34
- name,
35
- optional,
36
- typeAnnotation: {
37
- type: 'BooleanTypeAnnotation',
38
- },
39
- };
45
+ return emitBoolProp(name, optional);
40
46
  case 'StringTypeAnnotation':
41
- return {
42
- name,
43
- optional,
44
- typeAnnotation: {
45
- type: 'StringTypeAnnotation',
46
- },
47
- };
47
+ return emitStringProp(name, optional);
48
48
  case 'Int32':
49
49
  return {
50
50
  name,
@@ -54,26 +54,15 @@ function getPropertyType(
54
54
  },
55
55
  };
56
56
  case 'Double':
57
- return {
58
- name,
59
- optional,
60
- typeAnnotation: {
61
- type: 'DoubleTypeAnnotation',
62
- },
63
- };
57
+ return emitDoubleProp(name, optional);
64
58
  case 'Float':
65
- return {
66
- name,
67
- optional,
68
- typeAnnotation: {
69
- type: 'FloatTypeAnnotation',
70
- },
71
- };
59
+ return emitFloatProp(name, optional);
72
60
  case '$ReadOnly':
73
61
  return getPropertyType(
74
62
  name,
75
63
  optional,
76
64
  typeAnnotation.typeParameters.params[0],
65
+ parser,
77
66
  );
78
67
  case 'ObjectTypeAnnotation':
79
68
  return {
@@ -81,7 +70,9 @@ function getPropertyType(
81
70
  optional,
82
71
  typeAnnotation: {
83
72
  type: 'ObjectTypeAnnotation',
84
- properties: typeAnnotation.properties.map(buildPropertiesForEvent),
73
+ properties: typeAnnotation.properties.map(member =>
74
+ buildPropertiesForEvent(member, parser),
75
+ ),
85
76
  },
86
77
  };
87
78
  case 'UnionTypeAnnotation':
@@ -93,13 +84,104 @@ function getPropertyType(
93
84
  options: typeAnnotation.types.map(option => option.value),
94
85
  },
95
86
  };
87
+ case 'UnsafeMixed':
88
+ return {
89
+ name,
90
+ optional,
91
+ typeAnnotation: {
92
+ type: 'MixedTypeAnnotation',
93
+ },
94
+ };
95
+ case 'ArrayTypeAnnotation':
96
+ case '$ReadOnlyArray':
97
+ return {
98
+ name,
99
+ optional,
100
+ typeAnnotation: extractArrayElementType(typeAnnotation, name, parser),
101
+ };
96
102
  default:
97
- (type: empty);
98
103
  throw new Error(`Unable to determine event type for "${name}": ${type}`);
99
104
  }
100
105
  }
101
106
 
107
+ function extractArrayElementType(
108
+ typeAnnotation: $FlowFixMe,
109
+ name: string,
110
+ parser: Parser,
111
+ ): EventTypeAnnotation {
112
+ const type = extractTypeFromTypeAnnotation(typeAnnotation);
113
+
114
+ switch (type) {
115
+ case 'BooleanTypeAnnotation':
116
+ return {type: 'BooleanTypeAnnotation'};
117
+ case 'StringTypeAnnotation':
118
+ return {type: 'StringTypeAnnotation'};
119
+ case 'Int32':
120
+ return {type: 'Int32TypeAnnotation'};
121
+ case 'Float':
122
+ return {type: 'FloatTypeAnnotation'};
123
+ case 'NumberTypeAnnotation':
124
+ case 'Double':
125
+ return {
126
+ type: 'DoubleTypeAnnotation',
127
+ };
128
+ case 'UnionTypeAnnotation':
129
+ return {
130
+ type: 'StringEnumTypeAnnotation',
131
+ options: typeAnnotation.types.map(option => option.value),
132
+ };
133
+ case 'UnsafeMixed':
134
+ return {type: 'MixedTypeAnnotation'};
135
+ case 'ObjectTypeAnnotation':
136
+ return {
137
+ type: 'ObjectTypeAnnotation',
138
+ properties: typeAnnotation.properties.map(member =>
139
+ buildPropertiesForEvent(member, parser),
140
+ ),
141
+ };
142
+ case 'ArrayTypeAnnotation':
143
+ return {
144
+ type: 'ArrayTypeAnnotation',
145
+ elementType: extractArrayElementType(
146
+ typeAnnotation.elementType,
147
+ name,
148
+ parser,
149
+ ),
150
+ };
151
+ case '$ReadOnlyArray':
152
+ const genericParams = typeAnnotation.typeParameters.params;
153
+ if (genericParams.length !== 1) {
154
+ throw new Error(
155
+ `Events only supports arrays with 1 Generic type. Found ${
156
+ genericParams.length
157
+ } types:\n${prettify(genericParams)}`,
158
+ );
159
+ }
160
+ return {
161
+ type: 'ArrayTypeAnnotation',
162
+ elementType: extractArrayElementType(genericParams[0], name, parser),
163
+ };
164
+ default:
165
+ throw new Error(
166
+ `Unrecognized ${type} for Array ${name} in events.\n${prettify(
167
+ typeAnnotation,
168
+ )}`,
169
+ );
170
+ }
171
+ }
172
+
173
+ function prettify(jsonObject: $FlowFixMe): string {
174
+ return JSON.stringify(jsonObject, null, 2);
175
+ }
176
+
177
+ function extractTypeFromTypeAnnotation(typeAnnotation: $FlowFixMe): string {
178
+ return typeAnnotation.type === 'GenericTypeAnnotation'
179
+ ? typeAnnotation.id.name
180
+ : typeAnnotation.type;
181
+ }
182
+
102
183
  function findEventArgumentsAndType(
184
+ parser: Parser,
103
185
  typeAnnotation: $FlowFixMe,
104
186
  types: TypeMap,
105
187
  bubblingType: void | 'direct' | 'bubble',
@@ -109,9 +191,7 @@ function findEventArgumentsAndType(
109
191
  bubblingType: ?('direct' | 'bubble'),
110
192
  paperTopLevelNameDeprecated: ?$FlowFixMe,
111
193
  } {
112
- if (!typeAnnotation.id) {
113
- throw new Error("typeAnnotation of event doesn't have a name");
114
- }
194
+ throwIfEventHasNoName(typeAnnotation, parser);
115
195
  const name = typeAnnotation.id.name;
116
196
  if (name === '$ReadOnly') {
117
197
  return {
@@ -127,7 +207,7 @@ function findEventArgumentsAndType(
127
207
  : null;
128
208
  if (
129
209
  typeAnnotation.typeParameters.params[0].type ===
130
- 'NullLiteralTypeAnnotation'
210
+ parser.nullLiteralTypeAnnotation
131
211
  ) {
132
212
  return {
133
213
  argumentProps: [],
@@ -136,6 +216,7 @@ function findEventArgumentsAndType(
136
216
  };
137
217
  }
138
218
  return findEventArgumentsAndType(
219
+ parser,
139
220
  typeAnnotation.typeParameters.params[0],
140
221
  types,
141
222
  eventType,
@@ -143,6 +224,7 @@ function findEventArgumentsAndType(
143
224
  );
144
225
  } else if (types[name]) {
145
226
  return findEventArgumentsAndType(
227
+ parser,
146
228
  types[name].right,
147
229
  types,
148
230
  bubblingType,
@@ -157,32 +239,26 @@ function findEventArgumentsAndType(
157
239
  }
158
240
  }
159
241
 
160
- /* $FlowFixMe[missing-local-annot] The type annotation(s) required by Flow's
161
- * LTI update could not be added via codemod */
162
- function buildPropertiesForEvent(property): NamedShape<EventTypeAnnotation> {
242
+ function buildPropertiesForEvent(
243
+ /* $FlowFixMe[missing-local-annot] The type annotation(s) required by Flow's
244
+ * LTI update could not be added via codemod */
245
+ property,
246
+ parser: Parser,
247
+ ): NamedShape<EventTypeAnnotation> {
163
248
  const name = property.key.name;
164
- const optional =
165
- property.value.type === 'NullableTypeAnnotation' || property.optional;
249
+ const optional = parser.isOptionalProperty(property);
166
250
  let typeAnnotation =
167
251
  property.value.type === 'NullableTypeAnnotation'
168
252
  ? property.value.typeAnnotation
169
253
  : property.value;
170
254
 
171
- return getPropertyType(name, optional, typeAnnotation);
172
- }
173
-
174
- /* $FlowFixMe[missing-local-annot] The type annotation(s) required by Flow's
175
- * LTI update could not be added via codemod */
176
- function getEventArgument(argumentProps, name: $FlowFixMe) {
177
- return {
178
- type: 'ObjectTypeAnnotation',
179
- properties: argumentProps.map(buildPropertiesForEvent),
180
- };
255
+ return getPropertyType(name, optional, typeAnnotation, parser);
181
256
  }
182
257
 
183
258
  function buildEventSchema(
184
259
  types: TypeMap,
185
260
  property: EventTypeAST,
261
+ parser: Parser,
186
262
  ): ?EventTypeShape {
187
263
  const name = property.key.name;
188
264
  const optional =
@@ -202,40 +278,44 @@ function buildEventSchema(
202
278
  }
203
279
 
204
280
  const {argumentProps, bubblingType, paperTopLevelNameDeprecated} =
205
- findEventArgumentsAndType(typeAnnotation, types);
281
+ findEventArgumentsAndType(parser, typeAnnotation, types);
206
282
 
207
- if (bubblingType && argumentProps) {
208
- if (paperTopLevelNameDeprecated != null) {
209
- return {
210
- name,
211
- optional,
212
- bubblingType,
213
- paperTopLevelNameDeprecated,
214
- typeAnnotation: {
215
- type: 'EventTypeAnnotation',
216
- argument: getEventArgument(argumentProps, name),
217
- },
218
- };
219
- }
283
+ const nonNullableArgumentProps = throwIfArgumentPropsAreNull(
284
+ argumentProps,
285
+ name,
286
+ );
287
+ const nonNullableBubblingType = throwIfBubblingTypeIsNull(bubblingType, name);
220
288
 
289
+ if (paperTopLevelNameDeprecated != null) {
221
290
  return {
222
291
  name,
223
292
  optional,
224
- bubblingType,
293
+ bubblingType: nonNullableBubblingType,
294
+ paperTopLevelNameDeprecated,
225
295
  typeAnnotation: {
226
296
  type: 'EventTypeAnnotation',
227
- argument: getEventArgument(argumentProps, name),
297
+ argument: getEventArgument(
298
+ nonNullableArgumentProps,
299
+ buildPropertiesForEvent,
300
+ parser,
301
+ ),
228
302
  },
229
303
  };
230
304
  }
231
305
 
232
- if (argumentProps === null) {
233
- throw new Error(`Unable to determine event arguments for "${name}"`);
234
- }
235
-
236
- if (bubblingType === null) {
237
- throw new Error(`Unable to determine event arguments for "${name}"`);
238
- }
306
+ return {
307
+ name,
308
+ optional,
309
+ bubblingType: nonNullableBubblingType,
310
+ typeAnnotation: {
311
+ type: 'EventTypeAnnotation',
312
+ argument: getEventArgument(
313
+ nonNullableArgumentProps,
314
+ buildPropertiesForEvent,
315
+ parser,
316
+ ),
317
+ },
318
+ };
239
319
  }
240
320
 
241
321
  // $FlowFixMe[unclear-type] there's no flowtype for ASTs
@@ -250,10 +330,11 @@ type TypeMap = {
250
330
  function getEvents(
251
331
  eventTypeAST: $ReadOnlyArray<EventTypeAST>,
252
332
  types: TypeMap,
333
+ parser: Parser,
253
334
  ): $ReadOnlyArray<EventTypeShape> {
254
335
  return eventTypeAST
255
336
  .filter(property => property.type === 'ObjectTypeProperty')
256
- .map(property => buildEventSchema(types, property))
337
+ .map(property => buildEventSchema(types, property, parser))
257
338
  .filter(Boolean);
258
339
  }
259
340