@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
@@ -28,21 +28,14 @@ import type {
28
28
  const {flattenIntersectionType} = require('../parseTopLevelType');
29
29
  const {flattenProperties} = require('../components/componentsUtils');
30
30
 
31
- const {resolveTypeAnnotation} = require('../utils');
32
-
33
31
  const {parseObjectProperty} = require('../../parsers-commons');
34
32
 
35
33
  const {
36
34
  emitArrayType,
37
- emitBoolean,
38
35
  emitFunction,
39
- emitNumber,
40
- emitGenericObject,
36
+ emitDictionary,
41
37
  emitPromise,
42
38
  emitRootTag,
43
- emitVoid,
44
- emitString,
45
- emitMixed,
46
39
  emitUnion,
47
40
  emitCommonTypes,
48
41
  typeAliasResolution,
@@ -195,7 +188,9 @@ function translateTypeAnnotation(
195
188
  parser: Parser,
196
189
  ): Nullable<NativeModuleTypeAnnotation> {
197
190
  const {nullable, typeAnnotation, typeResolutionStatus} =
198
- resolveTypeAnnotation(typeScriptTypeAnnotation, types);
191
+ parser.getResolvedTypeAnnotation(typeScriptTypeAnnotation, types, parser);
192
+ const resolveTypeaAnnotationFn = parser.getResolveTypeAnnotationFN();
193
+ resolveTypeaAnnotationFn(typeScriptTypeAnnotation, types, parser);
199
194
 
200
195
  switch (typeAnnotation.type) {
201
196
  case 'TSArrayType': {
@@ -314,7 +309,7 @@ function translateTypeAnnotation(
314
309
  // check the property type to prevent developers from using unsupported types
315
310
  // the return value from `translateTypeAnnotation` is unused
316
311
  const propertyType = indexSignatures[0].typeAnnotation;
317
- translateTypeAnnotation(
312
+ const valueType = translateTypeAnnotation(
318
313
  hasteModuleName,
319
314
  propertyType,
320
315
  types,
@@ -325,7 +320,7 @@ function translateTypeAnnotation(
325
320
  parser,
326
321
  );
327
322
  // no need to do further checking
328
- return emitGenericObject(nullable);
323
+ return emitDictionary(nullable, valueType);
329
324
  }
330
325
  }
331
326
 
@@ -353,18 +348,6 @@ function translateTypeAnnotation(
353
348
  parser,
354
349
  );
355
350
  }
356
- case 'TSBooleanKeyword': {
357
- return emitBoolean(nullable);
358
- }
359
- case 'TSNumberKeyword': {
360
- return emitNumber(nullable);
361
- }
362
- case 'TSVoidKeyword': {
363
- return emitVoid(nullable);
364
- }
365
- case 'TSStringKeyword': {
366
- return emitString(nullable);
367
- }
368
351
  case 'TSFunctionType': {
369
352
  return emitFunction(
370
353
  nullable,
@@ -382,18 +365,27 @@ function translateTypeAnnotation(
382
365
  case 'TSUnionType': {
383
366
  return emitUnion(nullable, hasteModuleName, typeAnnotation, parser);
384
367
  }
385
- case 'TSUnknownKeyword': {
386
- if (cxxOnly) {
387
- return emitMixed(nullable);
388
- }
389
- // Fallthrough
390
- }
391
368
  default: {
392
- throw new UnsupportedTypeAnnotationParserError(
369
+ const commonType = emitCommonTypes(
393
370
  hasteModuleName,
371
+ types,
394
372
  typeAnnotation,
395
- parser.language(),
373
+ aliasMap,
374
+ enumMap,
375
+ tryParse,
376
+ cxxOnly,
377
+ nullable,
378
+ parser,
396
379
  );
380
+
381
+ if (!commonType) {
382
+ throw new UnsupportedTypeAnnotationParserError(
383
+ hasteModuleName,
384
+ typeAnnotation,
385
+ parser.language(),
386
+ );
387
+ }
388
+ return commonType;
397
389
  }
398
390
  }
399
391
  }
@@ -5,6 +5,13 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- import type {Parser} from '../parser';
8
+ import type { Parser } from '../parser';
9
+ import type { SchemaType } from '../../CodegenSchema';
10
+ import type { ParserType } from '../errors';
9
11
 
10
- export declare class TypeScriptParser implements Parser{}
12
+ export declare class TypeScriptParser implements Parser {
13
+ language(): ParserType;
14
+ parseFile(filename: string): SchemaType;
15
+ parseString(contents: string, filename?: string): SchemaType;
16
+ parseModuleFixture(filename: string): SchemaType;
17
+ }
@@ -38,6 +38,7 @@ function _toPrimitive(input, hint) {
38
38
  }
39
39
  return (hint === 'string' ? String : Number)(input);
40
40
  }
41
+ const invariant = require('invariant');
41
42
  const _require = require('./modules'),
42
43
  typeScriptTranslateTypeAnnotation =
43
44
  _require.typeScriptTranslateTypeAnnotation;
@@ -53,13 +54,19 @@ const _require4 = require('./components'),
53
54
  const _require5 = require('../schema.js'),
54
55
  wrapComponentSchema = _require5.wrapComponentSchema;
55
56
  const _require6 = require('../parsers-commons.js'),
56
- buildModuleSchema = _require6.buildModuleSchema;
57
- const _require7 = require('./utils'),
58
- resolveTypeAnnotation = _require7.resolveTypeAnnotation;
57
+ buildModuleSchema = _require6.buildModuleSchema,
58
+ extendsForProp = _require6.extendsForProp,
59
+ buildPropSchema = _require6.buildPropSchema;
60
+ const _require7 = require('./parseTopLevelType'),
61
+ parseTopLevelType = _require7.parseTopLevelType;
62
+ const _require8 = require('./components/componentsUtils'),
63
+ getSchemaInfo = _require8.getSchemaInfo,
64
+ getTypeAnnotation = _require8.getTypeAnnotation,
65
+ flattenProperties = _require8.flattenProperties;
59
66
  const fs = require('fs');
60
- const _require8 = require('../errors'),
67
+ const _require9 = require('../errors'),
61
68
  UnsupportedObjectPropertyTypeAnnotationParserError =
62
- _require8.UnsupportedObjectPropertyTypeAnnotationParserError;
69
+ _require9.UnsupportedObjectPropertyTypeAnnotationParserError;
63
70
  class TypeScriptParser {
64
71
  constructor() {
65
72
  _defineProperty(
@@ -67,6 +74,15 @@ class TypeScriptParser {
67
74
  'typeParameterInstantiation',
68
75
  'TSTypeParameterInstantiation',
69
76
  );
77
+ _defineProperty(this, 'typeAlias', 'TSTypeAliasDeclaration');
78
+ _defineProperty(this, 'enumDeclaration', 'TSEnumDeclaration');
79
+ _defineProperty(this, 'interfaceDeclaration', 'TSInterfaceDeclaration');
80
+ _defineProperty(this, 'nullLiteralTypeAnnotation', 'TSNullKeyword');
81
+ _defineProperty(
82
+ this,
83
+ 'undefinedLiteralTypeAnnotation',
84
+ 'TSUndefinedKeyword',
85
+ );
70
86
  }
71
87
  isProperty(property) {
72
88
  return property.type === 'TSPropertySignature';
@@ -86,7 +102,13 @@ class TypeScriptParser {
86
102
  return 'TypeScript';
87
103
  }
88
104
  nameForGenericTypeAnnotation(typeAnnotation) {
89
- return typeAnnotation.typeName.name;
105
+ var _typeAnnotation$typeN;
106
+ return typeAnnotation === null || typeAnnotation === void 0
107
+ ? void 0
108
+ : (_typeAnnotation$typeN = typeAnnotation.typeName) === null ||
109
+ _typeAnnotation$typeN === void 0
110
+ ? void 0
111
+ : _typeAnnotation$typeN.name;
90
112
  }
91
113
  checkIfInvalidModule(typeArguments) {
92
114
  return (
@@ -119,7 +141,6 @@ class TypeScriptParser {
119
141
  buildModuleSchema,
120
142
  Visitor,
121
143
  this,
122
- resolveTypeAnnotation,
123
144
  typeScriptTranslateTypeAnnotation,
124
145
  );
125
146
  }
@@ -224,6 +245,9 @@ class TypeScriptParser {
224
245
  node.extends[0].expression.name === 'TurboModule'
225
246
  );
226
247
  }
248
+ isGenericTypeAnnotation(type) {
249
+ return type === 'TSTypeReference';
250
+ }
227
251
  extractAnnotatedElement(typeAnnotation, types) {
228
252
  return types[typeAnnotation.typeParameters.params[0].typeName.name];
229
253
  }
@@ -306,6 +330,168 @@ class TypeScriptParser {
306
330
  getAnnotatedElementProperties(annotatedElement) {
307
331
  return annotatedElement.typeAnnotation.members;
308
332
  }
333
+ bodyProperties(typeAlias) {
334
+ return typeAlias.body.body;
335
+ }
336
+ convertKeywordToTypeAnnotation(keyword) {
337
+ switch (keyword) {
338
+ case 'TSBooleanKeyword':
339
+ return 'BooleanTypeAnnotation';
340
+ case 'TSNumberKeyword':
341
+ return 'NumberTypeAnnotation';
342
+ case 'TSVoidKeyword':
343
+ return 'VoidTypeAnnotation';
344
+ case 'TSStringKeyword':
345
+ return 'StringTypeAnnotation';
346
+ case 'TSUnknownKeyword':
347
+ return 'MixedTypeAnnotation';
348
+ }
349
+ return keyword;
350
+ }
351
+ argumentForProp(prop) {
352
+ return prop.expression;
353
+ }
354
+ nameForArgument(prop) {
355
+ return prop.expression.name;
356
+ }
357
+ isOptionalProperty(property) {
358
+ return property.optional || false;
359
+ }
360
+ getGetSchemaInfoFN() {
361
+ return getSchemaInfo;
362
+ }
363
+ getGetTypeAnnotationFN() {
364
+ return getTypeAnnotation;
365
+ }
366
+ getResolvedTypeAnnotation(
367
+ // TODO(T108222691): Use flow-types for @babel/parser
368
+ typeAnnotation,
369
+ types,
370
+ parser,
371
+ ) {
372
+ invariant(
373
+ typeAnnotation != null,
374
+ 'resolveTypeAnnotation(): typeAnnotation cannot be null',
375
+ );
376
+ let node =
377
+ typeAnnotation.type === 'TSTypeAnnotation'
378
+ ? typeAnnotation.typeAnnotation
379
+ : typeAnnotation;
380
+ let nullable = false;
381
+ let typeResolutionStatus = {
382
+ successful: false,
383
+ };
384
+ for (;;) {
385
+ const topLevelType = parseTopLevelType(node);
386
+ nullable = nullable || topLevelType.optional;
387
+ node = topLevelType.type;
388
+ if (node.type !== 'TSTypeReference') {
389
+ break;
390
+ }
391
+ const resolvedTypeAnnotation = types[node.typeName.name];
392
+ if (resolvedTypeAnnotation == null) {
393
+ break;
394
+ }
395
+ switch (resolvedTypeAnnotation.type) {
396
+ case parser.typeAlias: {
397
+ typeResolutionStatus = {
398
+ successful: true,
399
+ type: 'alias',
400
+ name: node.typeName.name,
401
+ };
402
+ node = resolvedTypeAnnotation.typeAnnotation;
403
+ break;
404
+ }
405
+ case parser.interfaceDeclaration: {
406
+ typeResolutionStatus = {
407
+ successful: true,
408
+ type: 'alias',
409
+ name: node.typeName.name,
410
+ };
411
+ node = resolvedTypeAnnotation;
412
+ break;
413
+ }
414
+ case parser.enumDeclaration: {
415
+ typeResolutionStatus = {
416
+ successful: true,
417
+ type: 'enum',
418
+ name: node.typeName.name,
419
+ };
420
+ node = resolvedTypeAnnotation;
421
+ break;
422
+ }
423
+ default: {
424
+ throw new TypeError(
425
+ `A non GenericTypeAnnotation must be a type declaration ('${parser.typeAlias}'), an interface ('${parser.interfaceDeclaration}'), or enum ('${parser.enumDeclaration}'). Instead, got the unsupported ${resolvedTypeAnnotation.type}.`,
426
+ );
427
+ }
428
+ }
429
+ }
430
+ return {
431
+ nullable: nullable,
432
+ typeAnnotation: node,
433
+ typeResolutionStatus,
434
+ };
435
+ }
436
+ getResolveTypeAnnotationFN() {
437
+ return (typeAnnotation, types, parser) => {
438
+ return this.getResolvedTypeAnnotation(typeAnnotation, types, parser);
439
+ };
440
+ }
441
+ isEvent(typeAnnotation) {
442
+ if (typeAnnotation.type !== 'TSTypeReference') {
443
+ return false;
444
+ }
445
+ const eventNames = new Set(['BubblingEventHandler', 'DirectEventHandler']);
446
+ return eventNames.has(typeAnnotation.typeName.name);
447
+ }
448
+ isProp(name, typeAnnotation) {
449
+ if (typeAnnotation.type !== 'TSTypeReference') {
450
+ return true;
451
+ }
452
+ const isStyle =
453
+ name === 'style' &&
454
+ typeAnnotation.type === 'GenericTypeAnnotation' &&
455
+ typeAnnotation.typeName.name === 'ViewStyleProp';
456
+ return !isStyle;
457
+ }
458
+ getProps(typeDefinition, types) {
459
+ const extendsProps = [];
460
+ const componentPropAsts = [];
461
+ const remaining = [];
462
+ for (const prop of typeDefinition) {
463
+ // find extends
464
+ if (prop.type === 'TSExpressionWithTypeArguments') {
465
+ const extend = extendsForProp(prop, types, this);
466
+ if (extend) {
467
+ extendsProps.push(extend);
468
+ continue;
469
+ }
470
+ }
471
+ remaining.push(prop);
472
+ }
473
+
474
+ // find events and props
475
+ for (const prop of flattenProperties(remaining, types)) {
476
+ const topLevelType = parseTopLevelType(
477
+ prop.typeAnnotation.typeAnnotation,
478
+ types,
479
+ );
480
+ if (
481
+ prop.type === 'TSPropertySignature' &&
482
+ !this.isEvent(topLevelType.type) &&
483
+ this.isProp(prop.key.name, prop)
484
+ ) {
485
+ componentPropAsts.push(prop);
486
+ }
487
+ }
488
+ return {
489
+ props: componentPropAsts
490
+ .map(property => buildPropSchema(property, types, this))
491
+ .filter(Boolean),
492
+ extendsProps,
493
+ };
494
+ }
309
495
  }
310
496
  module.exports = {
311
497
  TypeScriptParser,
@@ -20,10 +20,23 @@ import type {
20
20
  NativeModuleEnumMemberType,
21
21
  NativeModuleAliasMap,
22
22
  NativeModuleEnumMap,
23
+ PropTypeAnnotation,
24
+ ExtendsPropsShape,
23
25
  } from '../../CodegenSchema';
24
26
  import type {ParserType} from '../errors';
25
- import type {Parser} from '../parser';
26
- import type {ParserErrorCapturer, TypeDeclarationMap} from '../utils';
27
+ import type {
28
+ GetSchemaInfoFN,
29
+ GetTypeAnnotationFN,
30
+ Parser,
31
+ ResolveTypeAnnotationFN,
32
+ } from '../parser';
33
+ import type {
34
+ ParserErrorCapturer,
35
+ TypeDeclarationMap,
36
+ PropAST,
37
+ TypeResolutionStatus,
38
+ } from '../utils';
39
+ const invariant = require('invariant');
27
40
 
28
41
  const {typeScriptTranslateTypeAnnotation} = require('./modules');
29
42
 
@@ -34,9 +47,18 @@ const {buildSchema} = require('../parsers-commons');
34
47
  const {Visitor} = require('../parsers-primitives');
35
48
  const {buildComponentSchema} = require('./components');
36
49
  const {wrapComponentSchema} = require('../schema.js');
37
- const {buildModuleSchema} = require('../parsers-commons.js');
38
- const {resolveTypeAnnotation} = require('./utils');
50
+ const {
51
+ buildModuleSchema,
52
+ extendsForProp,
53
+ buildPropSchema,
54
+ } = require('../parsers-commons.js');
39
55
 
56
+ const {parseTopLevelType} = require('./parseTopLevelType');
57
+ const {
58
+ getSchemaInfo,
59
+ getTypeAnnotation,
60
+ flattenProperties,
61
+ } = require('./components/componentsUtils');
40
62
  const fs = require('fs');
41
63
 
42
64
  const {
@@ -45,6 +67,11 @@ const {
45
67
 
46
68
  class TypeScriptParser implements Parser {
47
69
  typeParameterInstantiation: string = 'TSTypeParameterInstantiation';
70
+ typeAlias: string = 'TSTypeAliasDeclaration';
71
+ enumDeclaration: string = 'TSEnumDeclaration';
72
+ interfaceDeclaration: string = 'TSInterfaceDeclaration';
73
+ nullLiteralTypeAnnotation: string = 'TSNullKeyword';
74
+ undefinedLiteralTypeAnnotation: string = 'TSUndefinedKeyword';
48
75
 
49
76
  isProperty(property: $FlowFixMe): boolean {
50
77
  return property.type === 'TSPropertySignature';
@@ -67,7 +94,7 @@ class TypeScriptParser implements Parser {
67
94
  }
68
95
 
69
96
  nameForGenericTypeAnnotation(typeAnnotation: $FlowFixMe): string {
70
- return typeAnnotation.typeName.name;
97
+ return typeAnnotation?.typeName?.name;
71
98
  }
72
99
 
73
100
  checkIfInvalidModule(typeArguments: $FlowFixMe): boolean {
@@ -108,7 +135,6 @@ class TypeScriptParser implements Parser {
108
135
  buildModuleSchema,
109
136
  Visitor,
110
137
  this,
111
- resolveTypeAnnotation,
112
138
  typeScriptTranslateTypeAnnotation,
113
139
  );
114
140
  }
@@ -210,6 +236,10 @@ class TypeScriptParser implements Parser {
210
236
  );
211
237
  }
212
238
 
239
+ isGenericTypeAnnotation(type: $FlowFixMe): boolean {
240
+ return type === 'TSTypeReference';
241
+ }
242
+
213
243
  extractAnnotatedElement(
214
244
  typeAnnotation: $FlowFixMe,
215
245
  types: TypeDeclarationMap,
@@ -303,6 +333,205 @@ class TypeScriptParser implements Parser {
303
333
  getAnnotatedElementProperties(annotatedElement: $FlowFixMe): $FlowFixMe {
304
334
  return annotatedElement.typeAnnotation.members;
305
335
  }
336
+
337
+ bodyProperties(typeAlias: TypeDeclarationMap): $ReadOnlyArray<$FlowFixMe> {
338
+ return typeAlias.body.body;
339
+ }
340
+
341
+ convertKeywordToTypeAnnotation(keyword: string): string {
342
+ switch (keyword) {
343
+ case 'TSBooleanKeyword':
344
+ return 'BooleanTypeAnnotation';
345
+ case 'TSNumberKeyword':
346
+ return 'NumberTypeAnnotation';
347
+ case 'TSVoidKeyword':
348
+ return 'VoidTypeAnnotation';
349
+ case 'TSStringKeyword':
350
+ return 'StringTypeAnnotation';
351
+ case 'TSUnknownKeyword':
352
+ return 'MixedTypeAnnotation';
353
+ }
354
+
355
+ return keyword;
356
+ }
357
+
358
+ argumentForProp(prop: PropAST): $FlowFixMe {
359
+ return prop.expression;
360
+ }
361
+
362
+ nameForArgument(prop: PropAST): $FlowFixMe {
363
+ return prop.expression.name;
364
+ }
365
+
366
+ isOptionalProperty(property: $FlowFixMe): boolean {
367
+ return property.optional || false;
368
+ }
369
+
370
+ getGetSchemaInfoFN(): GetSchemaInfoFN {
371
+ return getSchemaInfo;
372
+ }
373
+
374
+ getGetTypeAnnotationFN(): GetTypeAnnotationFN {
375
+ return getTypeAnnotation;
376
+ }
377
+
378
+ getResolvedTypeAnnotation(
379
+ // TODO(T108222691): Use flow-types for @babel/parser
380
+ typeAnnotation: $FlowFixMe,
381
+ types: TypeDeclarationMap,
382
+ parser: Parser,
383
+ ): {
384
+ nullable: boolean,
385
+ typeAnnotation: $FlowFixMe,
386
+ typeResolutionStatus: TypeResolutionStatus,
387
+ } {
388
+ invariant(
389
+ typeAnnotation != null,
390
+ 'resolveTypeAnnotation(): typeAnnotation cannot be null',
391
+ );
392
+
393
+ let node =
394
+ typeAnnotation.type === 'TSTypeAnnotation'
395
+ ? typeAnnotation.typeAnnotation
396
+ : typeAnnotation;
397
+ let nullable = false;
398
+ let typeResolutionStatus: TypeResolutionStatus = {
399
+ successful: false,
400
+ };
401
+
402
+ for (;;) {
403
+ const topLevelType = parseTopLevelType(node);
404
+ nullable = nullable || topLevelType.optional;
405
+ node = topLevelType.type;
406
+
407
+ if (node.type !== 'TSTypeReference') {
408
+ break;
409
+ }
410
+
411
+ const resolvedTypeAnnotation = types[node.typeName.name];
412
+ if (resolvedTypeAnnotation == null) {
413
+ break;
414
+ }
415
+
416
+ switch (resolvedTypeAnnotation.type) {
417
+ case parser.typeAlias: {
418
+ typeResolutionStatus = {
419
+ successful: true,
420
+ type: 'alias',
421
+ name: node.typeName.name,
422
+ };
423
+ node = resolvedTypeAnnotation.typeAnnotation;
424
+ break;
425
+ }
426
+ case parser.interfaceDeclaration: {
427
+ typeResolutionStatus = {
428
+ successful: true,
429
+ type: 'alias',
430
+ name: node.typeName.name,
431
+ };
432
+ node = resolvedTypeAnnotation;
433
+ break;
434
+ }
435
+ case parser.enumDeclaration: {
436
+ typeResolutionStatus = {
437
+ successful: true,
438
+ type: 'enum',
439
+ name: node.typeName.name,
440
+ };
441
+ node = resolvedTypeAnnotation;
442
+ break;
443
+ }
444
+ default: {
445
+ throw new TypeError(
446
+ `A non GenericTypeAnnotation must be a type declaration ('${parser.typeAlias}'), an interface ('${parser.interfaceDeclaration}'), or enum ('${parser.enumDeclaration}'). Instead, got the unsupported ${resolvedTypeAnnotation.type}.`,
447
+ );
448
+ }
449
+ }
450
+ }
451
+
452
+ return {
453
+ nullable: nullable,
454
+ typeAnnotation: node,
455
+ typeResolutionStatus,
456
+ };
457
+ }
458
+
459
+ getResolveTypeAnnotationFN(): ResolveTypeAnnotationFN {
460
+ return (
461
+ typeAnnotation: $FlowFixMe,
462
+ types: TypeDeclarationMap,
463
+ parser: Parser,
464
+ ) => {
465
+ return this.getResolvedTypeAnnotation(typeAnnotation, types, parser);
466
+ };
467
+ }
468
+
469
+ isEvent(typeAnnotation: $FlowFixMe): boolean {
470
+ if (typeAnnotation.type !== 'TSTypeReference') {
471
+ return false;
472
+ }
473
+ const eventNames = new Set(['BubblingEventHandler', 'DirectEventHandler']);
474
+ return eventNames.has(typeAnnotation.typeName.name);
475
+ }
476
+
477
+ isProp(name: string, typeAnnotation: $FlowFixMe): boolean {
478
+ if (typeAnnotation.type !== 'TSTypeReference') {
479
+ return true;
480
+ }
481
+ const isStyle =
482
+ name === 'style' &&
483
+ typeAnnotation.type === 'GenericTypeAnnotation' &&
484
+ typeAnnotation.typeName.name === 'ViewStyleProp';
485
+ return !isStyle;
486
+ }
487
+
488
+ getProps(
489
+ typeDefinition: $ReadOnlyArray<PropAST>,
490
+ types: TypeDeclarationMap,
491
+ ): {
492
+ props: $ReadOnlyArray<NamedShape<PropTypeAnnotation>>,
493
+ extendsProps: $ReadOnlyArray<ExtendsPropsShape>,
494
+ } {
495
+ const extendsProps: Array<ExtendsPropsShape> = [];
496
+ const componentPropAsts: Array<PropAST> = [];
497
+ const remaining: Array<PropAST> = [];
498
+
499
+ for (const prop of typeDefinition) {
500
+ // find extends
501
+ if (prop.type === 'TSExpressionWithTypeArguments') {
502
+ const extend = extendsForProp(prop, types, this);
503
+ if (extend) {
504
+ extendsProps.push(extend);
505
+ continue;
506
+ }
507
+ }
508
+
509
+ remaining.push(prop);
510
+ }
511
+
512
+ // find events and props
513
+ for (const prop of flattenProperties(remaining, types)) {
514
+ const topLevelType = parseTopLevelType(
515
+ prop.typeAnnotation.typeAnnotation,
516
+ types,
517
+ );
518
+
519
+ if (
520
+ prop.type === 'TSPropertySignature' &&
521
+ !this.isEvent(topLevelType.type) &&
522
+ this.isProp(prop.key.name, prop)
523
+ ) {
524
+ componentPropAsts.push(prop);
525
+ }
526
+ }
527
+
528
+ return {
529
+ props: componentPropAsts
530
+ .map(property => buildPropSchema(property, types, this))
531
+ .filter(Boolean),
532
+ extendsProps,
533
+ };
534
+ }
306
535
  }
307
536
 
308
537
  module.exports = {
@@ -34,6 +34,12 @@ function extractNativeModuleName(filename: string): string {
34
34
 
35
35
  export type ParserErrorCapturer = <T>(fn: () => T) => ?T;
36
36
 
37
+ // $FlowFixMe[unclear-type] there's no flowtype for ASTs
38
+ export type PropAST = Object;
39
+
40
+ // $FlowFixMe[unclear-type] there's no flowtype for ASTs
41
+ export type ASTNode = Object;
42
+
37
43
  function createParserErrorCapturer(): [
38
44
  Array<ParserError>,
39
45
  ParserErrorCapturer,