From ea9e78d426f88adfecc6806c6efaee72e13030ec Mon Sep 17 00:00:00 2001 From: Gabriel Donadel Dall'Agnol Date: Sat, 3 Dec 2022 14:18:46 -0800 Subject: [PATCH] feat: Extract case Array and ReadOnlyArray into a single emitArrayType function (#35546) Summary: This PR extracts the content of the codegen case `'Array'` and `'ReadOnlyArray'` into a single `emitArrayType` function inside the `parsers-primitives.js` file and uses it in both Flow and TypeScript parsers as requested on https://github.com/facebook/react-native/issues/34872. This also adds unit tests to the new `emitArrayType` function. ## Changelog [Internal] [Changed] - Extract the content of the case 'Array' and 'ReadOnlyArray' into a single emitArrayType function Pull Request resolved: https://github.com/facebook/react-native/pull/35546 Test Plan: Run `yarn jest react-native-codegen` and ensure CI is green ![image](https://user-images.githubusercontent.com/11707729/205375599-3bbf02bf-85b5-41e6-ae77-fc6e12bee538.png) Reviewed By: christophpurrer Differential Revision: D41700084 Pulled By: rshest fbshipit-source-id: 4bfd2d3ab3f1343bb401ba9c278dc0e0e1ea0989 --- .../__tests__/parsers-primitives-test.js | 84 +++++++++++++++++++ .../src/parsers/flow/modules/index.js | 10 +-- .../src/parsers/parsers-primitives.js | 30 +++++++ .../src/parsers/typescript/modules/index.js | 11 +-- 4 files changed, 118 insertions(+), 17 deletions(-) diff --git a/packages/react-native-codegen/src/parsers/__tests__/parsers-primitives-test.js b/packages/react-native-codegen/src/parsers/__tests__/parsers-primitives-test.js index 9f17748593d..acfead77c81 100644 --- a/packages/react-native-codegen/src/parsers/__tests__/parsers-primitives-test.js +++ b/packages/react-native-codegen/src/parsers/__tests__/parsers-primitives-test.js @@ -14,6 +14,7 @@ import type {UnionTypeAnnotationMemberType} from '../../CodegenSchema'; const { + emitArrayType, emitBoolean, emitDouble, emitFloat, @@ -912,3 +913,86 @@ describe('emitUnion', () => { }); }); }); + +describe('emitArrayType', () => { + const hasteModuleName = 'SampleTurboModule'; + + function emitArrayTypeForUnitTest( + typeAnnotation: $FlowFixMe, + nullable: boolean, + ): $FlowFixMe { + return emitArrayType( + hasteModuleName, + typeAnnotation, + parser, + /* types: TypeDeclarationMap */ + {}, + /* aliasMap: {...NativeModuleAliasMap} */ + {}, + /* cxxOnly: boolean */ + false, + nullable, + /* the translateTypeAnnotation function */ + (_, elementType) => elementType, + ); + } + + describe("when typeAnnotation doesn't have exactly one typeParameter", () => { + const nullable = false; + const typeAnnotation = { + typeParameters: { + params: [1, 2], + type: 'TypeParameterInstantiation', + }, + id: { + name: 'typeAnnotationName', + }, + }; + + it('throws an IncorrectlyParameterizedGenericParserError error', () => { + expect(() => + emitArrayTypeForUnitTest(typeAnnotation, nullable), + ).toThrow(); + }); + }); + + describe('when typeAnnotation has exactly one typeParameter', () => { + const typeAnnotation = { + typeParameters: { + params: [1], + type: 'TypeParameterInstantiation', + }, + id: { + name: 'typeAnnotationName', + }, + }; + + describe('when nullable is true', () => { + const nullable = true; + it('returns nullable type annotation', () => { + const result = emitArrayTypeForUnitTest(typeAnnotation, nullable); + const expected = { + type: 'NullableTypeAnnotation', + typeAnnotation: { + type: 'ArrayTypeAnnotation', + elementType: 1, + }, + }; + + expect(result).toEqual(expected); + }); + }); + describe('when nullable is false', () => { + const nullable = false; + it('returns non nullable type annotation', () => { + const result = emitArrayTypeForUnitTest(typeAnnotation, nullable); + const expected = { + type: 'ArrayTypeAnnotation', + elementType: 1, + }; + + expect(result).toEqual(expected); + }); + }); + }); +}); diff --git a/packages/react-native-codegen/src/parsers/flow/modules/index.js b/packages/react-native-codegen/src/parsers/flow/modules/index.js index 125e532ea6a..1365c0074d4 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/index.js +++ b/packages/react-native-codegen/src/parsers/flow/modules/index.js @@ -32,6 +32,7 @@ const { buildPropertySchema, } = require('../../parsers-commons'); const { + emitArrayType, emitBoolean, emitDouble, emitFloat, @@ -106,21 +107,14 @@ function translateTypeAnnotation( } case 'Array': case '$ReadOnlyArray': { - assertGenericTypeAnnotationHasExactlyOneTypeParameter( + return emitArrayType( hasteModuleName, typeAnnotation, parser, - ); - - return translateArrayTypeAnnotation( - hasteModuleName, types, aliasMap, cxxOnly, - typeAnnotation.type, - typeAnnotation.typeParameters.params[0], nullable, - language, translateTypeAnnotation, ); } diff --git a/packages/react-native-codegen/src/parsers/parsers-primitives.js b/packages/react-native-codegen/src/parsers/parsers-primitives.js index 8f238ce0e7e..5d4b41338f6 100644 --- a/packages/react-native-codegen/src/parsers/parsers-primitives.js +++ b/packages/react-native-codegen/src/parsers/parsers-primitives.js @@ -333,7 +333,37 @@ function translateArrayTypeAnnotation( } } +function emitArrayType( + hasteModuleName: string, + typeAnnotation: $FlowFixMe, + parser: Parser, + types: TypeDeclarationMap, + aliasMap: {...NativeModuleAliasMap}, + cxxOnly: boolean, + nullable: boolean, + translateTypeAnnotation: $FlowFixMe, +): Nullable { + assertGenericTypeAnnotationHasExactlyOneTypeParameter( + hasteModuleName, + typeAnnotation, + parser, + ); + + return translateArrayTypeAnnotation( + hasteModuleName, + types, + aliasMap, + cxxOnly, + typeAnnotation.type, + typeAnnotation.typeParameters.params[0], + nullable, + parser.language(), + translateTypeAnnotation, + ); +} + module.exports = { + emitArrayType, emitBoolean, emitDouble, emitFloat, diff --git a/packages/react-native-codegen/src/parsers/typescript/modules/index.js b/packages/react-native-codegen/src/parsers/typescript/modules/index.js index 5c829b03e8a..b9286989753 100644 --- a/packages/react-native-codegen/src/parsers/typescript/modules/index.js +++ b/packages/react-native-codegen/src/parsers/typescript/modules/index.js @@ -26,13 +26,13 @@ const {visit, isModuleRegistryCall, verifyPlatforms} = require('../../utils'); const {resolveTypeAnnotation, getTypes} = require('../utils.js'); const { - assertGenericTypeAnnotationHasExactlyOneTypeParameter, parseObjectProperty, translateDefault, buildPropertySchema, } = require('../../parsers-commons'); const { + emitArrayType, emitBoolean, emitDouble, emitFloat, @@ -145,21 +145,14 @@ function translateTypeAnnotation( } case 'Array': case 'ReadonlyArray': { - assertGenericTypeAnnotationHasExactlyOneTypeParameter( + return emitArrayType( hasteModuleName, typeAnnotation, parser, - ); - - return translateArrayTypeAnnotation( - hasteModuleName, types, aliasMap, cxxOnly, - typeAnnotation.type, - typeAnnotation.typeParameters.params[0], nullable, - language, translateTypeAnnotation, ); }