@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
@@ -9,43 +9,13 @@
9
9
  */
10
10
 
11
11
  'use strict';
12
- import type {ASTNode} from '../utils';
13
- import type {NamedShape} from '../../../CodegenSchema.js';
14
12
  const {
15
13
  parseTopLevelType,
16
14
  flattenIntersectionType,
17
15
  } = require('../parseTopLevelType');
18
- import type {TypeDeclarationMap} from '../../utils';
19
-
20
- function getProperties(
21
- typeName: string,
22
- types: TypeDeclarationMap,
23
- ): $FlowFixMe {
24
- const alias = types[typeName];
25
- if (!alias) {
26
- throw new Error(
27
- `Failed to find definition for "${typeName}", please check that you have a valid codegen typescript file`,
28
- );
29
- }
30
- const aliasKind =
31
- alias.type === 'TSInterfaceDeclaration' ? 'interface' : 'type';
32
-
33
- try {
34
- if (aliasKind === 'interface') {
35
- return [...(alias.extends ?? []), ...alias.body.body];
36
- }
37
-
38
- return (
39
- alias.typeAnnotation.members ||
40
- alias.typeAnnotation.typeParameters.params[0].members ||
41
- alias.typeAnnotation.typeParameters.params
42
- );
43
- } catch (e) {
44
- throw new Error(
45
- `Failed to find ${aliasKind} definition for "${typeName}", please check that you have a valid codegen typescript file`,
46
- );
47
- }
48
- }
16
+ const {verifyPropNotAlreadyDefined} = require('../../parsers-commons');
17
+ import type {TypeDeclarationMap, PropAST, ASTNode} from '../../utils';
18
+ import type {BuildSchemaFN, Parser} from '../../parser';
49
19
 
50
20
  function getUnionOfLiterals(
51
21
  name: string,
@@ -111,7 +81,8 @@ function detectArrayType<T>(
111
81
  typeAnnotation: $FlowFixMe | ASTNode,
112
82
  defaultValue: $FlowFixMe | void,
113
83
  types: TypeDeclarationMap,
114
- buildSchema: (property: PropAST, types: TypeDeclarationMap) => ?NamedShape<T>,
84
+ parser: Parser,
85
+ buildSchema: BuildSchemaFN<T>,
115
86
  ): $FlowFixMe {
116
87
  // Covers: readonly T[]
117
88
  if (
@@ -126,6 +97,7 @@ function detectArrayType<T>(
126
97
  typeAnnotation.typeAnnotation.elementType,
127
98
  defaultValue,
128
99
  types,
100
+ parser,
129
101
  buildSchema,
130
102
  ),
131
103
  };
@@ -140,6 +112,7 @@ function detectArrayType<T>(
140
112
  typeAnnotation.elementType,
141
113
  defaultValue,
142
114
  types,
115
+ parser,
143
116
  buildSchema,
144
117
  ),
145
118
  };
@@ -148,8 +121,8 @@ function detectArrayType<T>(
148
121
  // Covers: Array<T> and ReadonlyArray<T>
149
122
  if (
150
123
  typeAnnotation.type === 'TSTypeReference' &&
151
- (typeAnnotation.typeName.name === 'ReadonlyArray' ||
152
- typeAnnotation.typeName.name === 'Array')
124
+ (parser.getTypeAnnotationName(typeAnnotation) === 'ReadonlyArray' ||
125
+ parser.getTypeAnnotationName(typeAnnotation) === 'Array')
153
126
  ) {
154
127
  return {
155
128
  type: 'ArrayTypeAnnotation',
@@ -158,6 +131,7 @@ function detectArrayType<T>(
158
131
  typeAnnotation.typeParameters.params[0],
159
132
  defaultValue,
160
133
  types,
134
+ parser,
161
135
  buildSchema,
162
136
  ),
163
137
  };
@@ -169,11 +143,12 @@ function detectArrayType<T>(
169
143
  function buildObjectType<T>(
170
144
  rawProperties: Array<$FlowFixMe>,
171
145
  types: TypeDeclarationMap,
172
- buildSchema: (property: PropAST, types: TypeDeclarationMap) => ?NamedShape<T>,
146
+ parser: Parser,
147
+ buildSchema: BuildSchemaFN<T>,
173
148
  ): $FlowFixMe {
174
- const flattenedProperties = flattenProperties(rawProperties, types);
149
+ const flattenedProperties = flattenProperties(rawProperties, types, parser);
175
150
  const properties = flattenedProperties
176
- .map(prop => buildSchema(prop, types))
151
+ .map(prop => buildSchema(prop, types, parser))
177
152
  .filter(Boolean);
178
153
 
179
154
  return {
@@ -189,17 +164,24 @@ function getCommonTypeAnnotation<T>(
189
164
  typeAnnotation: $FlowFixMe,
190
165
  defaultValue: $FlowFixMe | void,
191
166
  types: TypeDeclarationMap,
192
- buildSchema: (property: PropAST, types: TypeDeclarationMap) => ?NamedShape<T>,
167
+ parser: Parser,
168
+ buildSchema: BuildSchemaFN<T>,
193
169
  ): $FlowFixMe {
194
170
  switch (type) {
195
171
  case 'TSTypeLiteral':
196
- return buildObjectType(typeAnnotation.members, types, buildSchema);
172
+ return buildObjectType(
173
+ typeAnnotation.members,
174
+ types,
175
+ parser,
176
+ buildSchema,
177
+ );
197
178
  case 'TSInterfaceDeclaration':
198
- return buildObjectType([typeAnnotation], types, buildSchema);
179
+ return buildObjectType([typeAnnotation], types, parser, buildSchema);
199
180
  case 'TSIntersectionType':
200
181
  return buildObjectType(
201
182
  flattenIntersectionType(typeAnnotation, types),
202
183
  types,
184
+ parser,
203
185
  buildSchema,
204
186
  );
205
187
  case 'ImageSource':
@@ -276,7 +258,8 @@ function getTypeAnnotationForArray<T>(
276
258
  typeAnnotation: $FlowFixMe,
277
259
  defaultValue: $FlowFixMe | void,
278
260
  types: TypeDeclarationMap,
279
- buildSchema: (property: PropAST, types: TypeDeclarationMap) => ?NamedShape<T>,
261
+ parser: Parser,
262
+ buildSchema: BuildSchemaFN<T>,
280
263
  ): $FlowFixMe {
281
264
  // unpack WithDefault, (T) or T|U
282
265
  const topLevelType = parseTopLevelType(typeAnnotation, types);
@@ -297,6 +280,7 @@ function getTypeAnnotationForArray<T>(
297
280
  extractedTypeAnnotation,
298
281
  defaultValue,
299
282
  types,
283
+ parser,
300
284
  buildSchema,
301
285
  );
302
286
  if (arrayType) {
@@ -322,6 +306,7 @@ function getTypeAnnotationForArray<T>(
322
306
  extractedTypeAnnotation,
323
307
  defaultValue,
324
308
  types,
309
+ parser,
325
310
  buildSchema,
326
311
  );
327
312
  if (common) {
@@ -370,8 +355,10 @@ function getTypeAnnotation<T>(
370
355
  name: string,
371
356
  annotation: $FlowFixMe | ASTNode,
372
357
  defaultValue: $FlowFixMe | void,
358
+ withNullDefault: boolean, // Just to make `getTypeAnnotation` signature match with the one from Flow
373
359
  types: TypeDeclarationMap,
374
- buildSchema: (property: PropAST, types: TypeDeclarationMap) => ?NamedShape<T>,
360
+ parser: Parser,
361
+ buildSchema: BuildSchemaFN<T>,
375
362
  ): $FlowFixMe {
376
363
  // unpack WithDefault, (T) or T|U
377
364
  const topLevelType = parseTopLevelType(annotation, types);
@@ -381,6 +368,7 @@ function getTypeAnnotation<T>(
381
368
  typeAnnotation,
382
369
  defaultValue,
383
370
  types,
371
+ parser,
384
372
  buildSchema,
385
373
  );
386
374
  if (arrayType) {
@@ -390,7 +378,7 @@ function getTypeAnnotation<T>(
390
378
  const type =
391
379
  typeAnnotation.type === 'TSTypeReference' ||
392
380
  typeAnnotation.type === 'TSTypeAliasDeclaration'
393
- ? typeAnnotation.typeName.name
381
+ ? parser.getTypeAnnotationName(typeAnnotation)
394
382
  : typeAnnotation.type;
395
383
 
396
384
  const common = getCommonTypeAnnotation(
@@ -400,6 +388,7 @@ function getTypeAnnotation<T>(
400
388
  typeAnnotation,
401
389
  defaultValue,
402
390
  types,
391
+ parser,
403
392
  buildSchema,
404
393
  );
405
394
  if (common) {
@@ -425,7 +414,6 @@ function getTypeAnnotation<T>(
425
414
  `Cannot use "${type}" type annotation for "${name}": must use a specific function type like BubblingEventHandler, or DirectEventHandler`,
426
415
  );
427
416
  default:
428
- (type: empty);
429
417
  throw new Error(`Unknown prop type for "${name}": "${type}"`);
430
418
  }
431
419
  }
@@ -435,6 +423,7 @@ type SchemaInfo = {
435
423
  optional: boolean,
436
424
  typeAnnotation: $FlowFixMe,
437
425
  defaultValue: $FlowFixMe,
426
+ withNullDefault: boolean, // Just to make `getTypeAnnotation` signature match with the one from Flow
438
427
  };
439
428
 
440
429
  function getSchemaInfo(
@@ -460,26 +449,14 @@ function getSchemaInfo(
460
449
  optional: property.optional || topLevelType.optional,
461
450
  typeAnnotation: topLevelType.type,
462
451
  defaultValue: topLevelType.defaultValue,
452
+ withNullDefault: false, // Just to make `getTypeAnnotation` signature match with the one from Flow
463
453
  };
464
454
  }
465
455
 
466
- // $FlowFixMe[unclear-type] TODO(T108222691): Use flow-types for @babel/parser
467
- type PropAST = Object;
468
-
469
- function verifyPropNotAlreadyDefined(
470
- props: $ReadOnlyArray<PropAST>,
471
- needleProp: PropAST,
472
- ) {
473
- const propName = needleProp.key.name;
474
- const foundProp = props.some(prop => prop.key.name === propName);
475
- if (foundProp) {
476
- throw new Error(`A prop was already defined with the name ${propName}`);
477
- }
478
- }
479
-
480
456
  function flattenProperties(
481
457
  typeDefinition: $ReadOnlyArray<PropAST>,
482
458
  types: TypeDeclarationMap,
459
+ parser: Parser,
483
460
  ): $ReadOnlyArray<PropAST> {
484
461
  return typeDefinition
485
462
  .map(property => {
@@ -487,23 +464,29 @@ function flattenProperties(
487
464
  return property;
488
465
  } else if (property.type === 'TSTypeReference') {
489
466
  return flattenProperties(
490
- getProperties(property.typeName.name, types),
467
+ parser.getProperties(property.typeName.name, types),
491
468
  types,
469
+ parser,
492
470
  );
493
471
  } else if (
494
472
  property.type === 'TSExpressionWithTypeArguments' ||
495
473
  property.type === 'TSInterfaceHeritage'
496
474
  ) {
497
475
  return flattenProperties(
498
- getProperties(property.expression.name, types),
476
+ parser.getProperties(property.expression.name, types),
499
477
  types,
478
+ parser,
500
479
  );
501
480
  } else if (property.type === 'TSTypeLiteral') {
502
- return flattenProperties(property.members, types);
481
+ return flattenProperties(property.members, types, parser);
503
482
  } else if (property.type === 'TSInterfaceDeclaration') {
504
- return flattenProperties(getProperties(property.id.name, types), types);
483
+ return flattenProperties(
484
+ parser.getProperties(property.id.name, types),
485
+ types,
486
+ parser,
487
+ );
505
488
  } else if (property.type === 'TSIntersectionType') {
506
- return flattenProperties(property.types, types);
489
+ return flattenProperties(property.types, types, parser);
507
490
  } else {
508
491
  throw new Error(
509
492
  `${property.type} is not a supported object literal type.`,
@@ -527,7 +510,6 @@ function flattenProperties(
527
510
  }
528
511
 
529
512
  module.exports = {
530
- getProperties,
531
513
  getSchemaInfo,
532
514
  getTypeAnnotation,
533
515
  flattenProperties,
@@ -14,6 +14,24 @@ const _require = require('./componentsUtils'),
14
14
  flattenProperties = _require.flattenProperties;
15
15
  const _require2 = require('../parseTopLevelType'),
16
16
  parseTopLevelType = _require2.parseTopLevelType;
17
+ const _require3 = require('../../error-utils'),
18
+ throwIfEventHasNoName = _require3.throwIfEventHasNoName,
19
+ throwIfBubblingTypeIsNull = _require3.throwIfBubblingTypeIsNull,
20
+ throwIfArgumentPropsAreNull = _require3.throwIfArgumentPropsAreNull;
21
+ const _require4 = require('../../parsers-commons'),
22
+ getEventArgument = _require4.getEventArgument,
23
+ buildPropertiesForEvent = _require4.buildPropertiesForEvent,
24
+ handleEventHandler = _require4.handleEventHandler,
25
+ emitBuildEventSchema = _require4.emitBuildEventSchema;
26
+ const _require5 = require('../../parsers-primitives'),
27
+ emitBoolProp = _require5.emitBoolProp,
28
+ emitDoubleProp = _require5.emitDoubleProp,
29
+ emitFloatProp = _require5.emitFloatProp,
30
+ emitMixedProp = _require5.emitMixedProp,
31
+ emitStringProp = _require5.emitStringProp,
32
+ emitInt32Prop = _require5.emitInt32Prop,
33
+ emitObjectProp = _require5.emitObjectProp,
34
+ emitUnionProp = _require5.emitUnionProp;
17
35
  function getPropertyType(
18
36
  /* $FlowFixMe[missing-local-annot] The type annotation(s) required by Flow's
19
37
  * LTI update could not be added via codemod */
@@ -22,79 +40,120 @@ function getPropertyType(
22
40
  /* $FlowFixMe[missing-local-annot] The type annotation(s) required by Flow's
23
41
  * LTI update could not be added via codemod */
24
42
  annotation,
43
+ parser,
25
44
  ) {
26
45
  const topLevelType = parseTopLevelType(annotation);
27
46
  const typeAnnotation = topLevelType.type;
28
47
  const optional = optionalProperty || topLevelType.optional;
29
48
  const type =
30
49
  typeAnnotation.type === 'TSTypeReference'
31
- ? typeAnnotation.typeName.name
50
+ ? parser.getTypeAnnotationName(typeAnnotation)
32
51
  : typeAnnotation.type;
33
52
  switch (type) {
34
53
  case 'TSBooleanKeyword':
54
+ return emitBoolProp(name, optional);
55
+ case 'TSStringKeyword':
56
+ return emitStringProp(name, optional);
57
+ case 'Int32':
58
+ return emitInt32Prop(name, optional);
59
+ case 'Double':
60
+ return emitDoubleProp(name, optional);
61
+ case 'Float':
62
+ return emitFloatProp(name, optional);
63
+ case 'TSTypeLiteral':
64
+ return emitObjectProp(
65
+ name,
66
+ optional,
67
+ parser,
68
+ typeAnnotation,
69
+ extractArrayElementType,
70
+ );
71
+ case 'TSUnionType':
72
+ return emitUnionProp(name, optional, parser, typeAnnotation);
73
+ case 'UnsafeMixed':
74
+ return emitMixedProp(name, optional);
75
+ case 'TSArrayType':
35
76
  return {
36
77
  name,
37
78
  optional,
38
- typeAnnotation: {
39
- type: 'BooleanTypeAnnotation',
40
- },
79
+ typeAnnotation: extractArrayElementType(typeAnnotation, name, parser),
80
+ };
81
+ default:
82
+ throw new Error(`Unable to determine event type for "${name}": ${type}`);
83
+ }
84
+ }
85
+ function extractArrayElementType(typeAnnotation, name, parser) {
86
+ const type = extractTypeFromTypeAnnotation(typeAnnotation, parser);
87
+ switch (type) {
88
+ case 'TSParenthesizedType':
89
+ return extractArrayElementType(
90
+ typeAnnotation.typeAnnotation,
91
+ name,
92
+ parser,
93
+ );
94
+ case 'TSBooleanKeyword':
95
+ return {
96
+ type: 'BooleanTypeAnnotation',
41
97
  };
42
98
  case 'TSStringKeyword':
43
99
  return {
44
- name,
45
- optional,
46
- typeAnnotation: {
47
- type: 'StringTypeAnnotation',
48
- },
100
+ type: 'StringTypeAnnotation',
101
+ };
102
+ case 'Float':
103
+ return {
104
+ type: 'FloatTypeAnnotation',
49
105
  };
50
106
  case 'Int32':
51
107
  return {
52
- name,
53
- optional,
54
- typeAnnotation: {
55
- type: 'Int32TypeAnnotation',
56
- },
108
+ type: 'Int32TypeAnnotation',
57
109
  };
110
+ case 'TSNumberKeyword':
58
111
  case 'Double':
59
112
  return {
60
- name,
61
- optional,
62
- typeAnnotation: {
63
- type: 'DoubleTypeAnnotation',
64
- },
113
+ type: 'DoubleTypeAnnotation',
65
114
  };
66
- case 'Float':
115
+ case 'TSUnionType':
67
116
  return {
68
- name,
69
- optional,
70
- typeAnnotation: {
71
- type: 'FloatTypeAnnotation',
72
- },
117
+ type: 'StringEnumTypeAnnotation',
118
+ options: typeAnnotation.types.map(option =>
119
+ parser.getLiteralValue(option),
120
+ ),
73
121
  };
74
122
  case 'TSTypeLiteral':
75
123
  return {
76
- name,
77
- optional,
78
- typeAnnotation: {
79
- type: 'ObjectTypeAnnotation',
80
- properties: typeAnnotation.members.map(buildPropertiesForEvent),
81
- },
124
+ type: 'ObjectTypeAnnotation',
125
+ properties: parser
126
+ .getObjectProperties(typeAnnotation)
127
+ .map(member =>
128
+ buildPropertiesForEvent(member, parser, getPropertyType),
129
+ ),
82
130
  };
83
- case 'TSUnionType':
131
+ case 'TSArrayType':
84
132
  return {
85
- name,
86
- optional,
87
- typeAnnotation: {
88
- type: 'StringEnumTypeAnnotation',
89
- options: typeAnnotation.types.map(option => option.literal.value),
90
- },
133
+ type: 'ArrayTypeAnnotation',
134
+ elementType: extractArrayElementType(
135
+ typeAnnotation.elementType,
136
+ name,
137
+ parser,
138
+ ),
91
139
  };
92
140
  default:
93
- type;
94
- throw new Error(`Unable to determine event type for "${name}": ${type}`);
141
+ throw new Error(
142
+ `Unrecognized ${type} for Array ${name} in events.\n${JSON.stringify(
143
+ typeAnnotation,
144
+ null,
145
+ 2,
146
+ )}`,
147
+ );
95
148
  }
96
149
  }
150
+ function extractTypeFromTypeAnnotation(typeAnnotation, parser) {
151
+ return typeAnnotation.type === 'TSTypeReference'
152
+ ? parser.getTypeAnnotationName(typeAnnotation)
153
+ : typeAnnotation.type;
154
+ }
97
155
  function findEventArgumentsAndType(
156
+ parser,
98
157
  typeAnnotation,
99
158
  types,
100
159
  bubblingType,
@@ -102,57 +161,43 @@ function findEventArgumentsAndType(
102
161
  ) {
103
162
  if (typeAnnotation.type === 'TSInterfaceDeclaration') {
104
163
  return {
105
- argumentProps: flattenProperties([typeAnnotation], types),
164
+ argumentProps: flattenProperties([typeAnnotation], types, parser),
106
165
  paperTopLevelNameDeprecated: paperName,
107
166
  bubblingType,
108
167
  };
109
168
  }
110
169
  if (typeAnnotation.type === 'TSTypeLiteral') {
111
170
  return {
112
- argumentProps: typeAnnotation.members,
171
+ argumentProps: parser.getObjectProperties(typeAnnotation),
113
172
  paperTopLevelNameDeprecated: paperName,
114
173
  bubblingType,
115
174
  };
116
175
  }
117
- if (!typeAnnotation.typeName) {
118
- throw new Error("typeAnnotation of event doesn't have a name");
119
- }
120
- const name = typeAnnotation.typeName.name;
176
+ throwIfEventHasNoName(typeAnnotation, parser);
177
+ const name = parser.getTypeAnnotationName(typeAnnotation);
121
178
  if (name === 'Readonly') {
122
179
  return findEventArgumentsAndType(
180
+ parser,
123
181
  typeAnnotation.typeParameters.params[0],
124
182
  types,
125
183
  bubblingType,
126
184
  paperName,
127
185
  );
128
186
  } else if (name === 'BubblingEventHandler' || name === 'DirectEventHandler') {
129
- const eventType = name === 'BubblingEventHandler' ? 'bubble' : 'direct';
130
- const paperTopLevelNameDeprecated =
131
- typeAnnotation.typeParameters.params.length > 1
132
- ? typeAnnotation.typeParameters.params[1].literal.value
133
- : null;
134
- switch (typeAnnotation.typeParameters.params[0].type) {
135
- case 'TSNullKeyword':
136
- case 'TSUndefinedKeyword':
137
- return {
138
- argumentProps: [],
139
- bubblingType: eventType,
140
- paperTopLevelNameDeprecated,
141
- };
142
- default:
143
- return findEventArgumentsAndType(
144
- typeAnnotation.typeParameters.params[0],
145
- types,
146
- eventType,
147
- paperTopLevelNameDeprecated,
148
- );
149
- }
187
+ return handleEventHandler(
188
+ name,
189
+ typeAnnotation,
190
+ parser,
191
+ types,
192
+ findEventArgumentsAndType,
193
+ );
150
194
  } else if (types[name]) {
151
195
  let elementType = types[name];
152
196
  if (elementType.type === 'TSTypeAliasDeclaration') {
153
197
  elementType = elementType.typeAnnotation;
154
198
  }
155
199
  return findEventArgumentsAndType(
200
+ parser,
156
201
  elementType,
157
202
  types,
158
203
  bubblingType,
@@ -167,27 +212,9 @@ function findEventArgumentsAndType(
167
212
  }
168
213
  }
169
214
 
170
- /* $FlowFixMe[missing-local-annot] The type annotation(s) required by Flow's
171
- * LTI update could not be added via codemod */
172
- function buildPropertiesForEvent(property) {
173
- const name = property.key.name;
174
- const optional = property.optional || false;
175
- let typeAnnotation = property.typeAnnotation.typeAnnotation;
176
- return getPropertyType(name, optional, typeAnnotation);
177
- }
178
-
179
- /* $FlowFixMe[missing-local-annot] The type annotation(s) required by Flow's
180
- * LTI update could not be added via codemod */
181
- function getEventArgument(argumentProps, name) {
182
- return {
183
- type: 'ObjectTypeAnnotation',
184
- properties: argumentProps.map(buildPropertiesForEvent),
185
- };
186
- }
187
-
188
215
  // $FlowFixMe[unclear-type] TODO(T108222691): Use flow-types for @babel/parser
189
216
 
190
- function buildEventSchema(types, property) {
217
+ function buildEventSchema(types, property, parser) {
191
218
  // unpack WithDefault, (T) or T|U
192
219
  const topLevelType = parseTopLevelType(
193
220
  property.typeAnnotation.typeAnnotation,
@@ -197,6 +224,7 @@ function buildEventSchema(types, property) {
197
224
  const typeAnnotation = topLevelType.type;
198
225
  const optional = property.optional || topLevelType.optional;
199
226
  const _findEventArgumentsAn = findEventArgumentsAndType(
227
+ parser,
200
228
  typeAnnotation,
201
229
  types,
202
230
  ),
@@ -204,37 +232,30 @@ function buildEventSchema(types, property) {
204
232
  bubblingType = _findEventArgumentsAn.bubblingType,
205
233
  paperTopLevelNameDeprecated =
206
234
  _findEventArgumentsAn.paperTopLevelNameDeprecated;
207
- if (!argumentProps) {
208
- throw new Error(`Unable to determine event arguments for "${name}"`);
209
- } else if (!bubblingType) {
210
- throw new Error(`Unable to determine event bubbling type for "${name}"`);
211
- } else {
212
- if (paperTopLevelNameDeprecated != null) {
213
- return {
214
- name,
215
- optional,
216
- bubblingType,
217
- paperTopLevelNameDeprecated,
218
- typeAnnotation: {
219
- type: 'EventTypeAnnotation',
220
- argument: getEventArgument(argumentProps, name),
221
- },
222
- };
223
- }
224
- return {
225
- name,
226
- optional,
227
- bubblingType,
228
- typeAnnotation: {
229
- type: 'EventTypeAnnotation',
230
- argument: getEventArgument(argumentProps, name),
231
- },
232
- };
233
- }
235
+ const nonNullableArgumentProps = throwIfArgumentPropsAreNull(
236
+ argumentProps,
237
+ name,
238
+ );
239
+ const nonNullableBubblingType = throwIfBubblingTypeIsNull(bubblingType, name);
240
+ const argument = getEventArgument(
241
+ nonNullableArgumentProps,
242
+ parser,
243
+ getPropertyType,
244
+ );
245
+ return emitBuildEventSchema(
246
+ paperTopLevelNameDeprecated,
247
+ name,
248
+ optional,
249
+ nonNullableBubblingType,
250
+ argument,
251
+ );
234
252
  }
235
- function getEvents(eventTypeAST, types) {
236
- return eventTypeAST.map(property => buildEventSchema(types, property));
253
+ function getEvents(eventTypeAST, types, parser) {
254
+ return eventTypeAST
255
+ .map(property => buildEventSchema(types, property, parser))
256
+ .filter(Boolean);
237
257
  }
238
258
  module.exports = {
239
259
  getEvents,
260
+ extractArrayElementType,
240
261
  };