From 9b0e2d1a808e32e81755d22265c620ff398adf8a Mon Sep 17 00:00:00 2001 From: "Zihan Chen (MSFT)" <53799235+ZihanChen-MSFT@users.noreply.github.com> Date: Mon, 14 Nov 2022 14:23:51 -0800 Subject: [PATCH 01/12] Add `T` in `Promise` in codegen --- packages/react-native-codegen/src/CodegenSchema.js | 5 +++-- .../src/parsers/flow/modules/index.js | 12 +++++++++++- .../src/parsers/parsers-primitives.js | 13 +++++++++++++ .../src/parsers/typescript/modules/index.js | 12 +++++++++++- 4 files changed, 38 insertions(+), 4 deletions(-) diff --git a/packages/react-native-codegen/src/CodegenSchema.js b/packages/react-native-codegen/src/CodegenSchema.js index 6884ca30710b..3cb5e1fb26b4 100644 --- a/packages/react-native-codegen/src/CodegenSchema.js +++ b/packages/react-native-codegen/src/CodegenSchema.js @@ -297,8 +297,9 @@ export type NativeModuleTypeAliasTypeAnnotation = $ReadOnly<{ name: string, }>; -export type NativeModulePromiseTypeAnnotation = $ReadOnly<{ +export type NativeModulePromiseTypeAnnotation = $ReadOnly<{ type: 'PromiseTypeAnnotation', + elementType?: T, }>; export type UnionTypeAnnotationMemberType = @@ -346,5 +347,5 @@ export type NativeModuleTypeAnnotation = type NativeModuleParamOnlyTypeAnnotation = NativeModuleFunctionTypeAnnotation; type NativeModuleReturnOnlyTypeAnnotation = - | NativeModulePromiseTypeAnnotation + | NativeModulePromiseTypeAnnotation> | VoidTypeAnnotation; 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 90f3568c406f..6b1155106722 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/index.js +++ b/packages/react-native-codegen/src/parsers/flow/modules/index.js @@ -150,7 +150,17 @@ function translateTypeAnnotation( return emitRootTag(nullable); } case 'Promise': { - return emitPromise(hasteModuleName, typeAnnotation, parser, nullable); + return emitPromise( + hasteModuleName, + typeAnnotation, + parser, + nullable, + types, + aliasMap, + tryParse, + cxxOnly, + translateTypeAnnotation, + ); } case 'Array': case '$ReadOnlyArray': { diff --git a/packages/react-native-codegen/src/parsers/parsers-primitives.js b/packages/react-native-codegen/src/parsers/parsers-primitives.js index 5a3f4b04314f..a65e62569dc0 100644 --- a/packages/react-native-codegen/src/parsers/parsers-primitives.js +++ b/packages/react-native-codegen/src/parsers/parsers-primitives.js @@ -186,6 +186,11 @@ function emitPromise( typeAnnotation: $FlowFixMe, parser: Parser, nullable: boolean, + types: TypeDeclarationMap, + aliasMap: {...NativeModuleAliasMap}, + tryParse: ParserErrorCapturer, + cxxOnly: boolean, + translateTypeAnnotation: $FlowFixMe, ): Nullable { assertGenericTypeAnnotationHasExactlyOneTypeParameter( hasteModuleName, @@ -195,6 +200,14 @@ function emitPromise( return wrapNullable(nullable, { type: 'PromiseTypeAnnotation', + elementType: translateTypeAnnotation( + hasteModuleName, + typeAnnotation.typeParameters.params[0], + types, + aliasMap, + tryParse, + cxxOnly, + ), }); } 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 c184e715479a..058b32094846 100644 --- a/packages/react-native-codegen/src/parsers/typescript/modules/index.js +++ b/packages/react-native-codegen/src/parsers/typescript/modules/index.js @@ -185,7 +185,17 @@ function translateTypeAnnotation( return emitRootTag(nullable); } case 'Promise': { - return emitPromise(hasteModuleName, typeAnnotation, parser, nullable); + return emitPromise( + hasteModuleName, + typeAnnotation, + parser, + nullable, + types, + aliasMap, + tryParse, + cxxOnly, + translateTypeAnnotation, + ); } case 'Array': case 'ReadonlyArray': { From 8be793bc3f5369f1aad1884daba2474a1ef6f0d0 Mon Sep 17 00:00:00 2001 From: "Zihan Chen (MSFT)" <53799235+ZihanChen-MSFT@users.noreply.github.com> Date: Mon, 14 Nov 2022 14:26:16 -0800 Subject: [PATCH 02/12] --updateSnapshot --- .../module-parser-snapshot-test.js.snap | 31 ++++++++++++++++--- ...script-module-parser-snapshot-test.js.snap | 31 ++++++++++++++++--- 2 files changed, 54 insertions(+), 8 deletions(-) diff --git a/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap b/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap index 32222a962a22..8b5278ba4673 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap +++ b/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap @@ -1506,7 +1506,20 @@ exports[`RN Codegen Flow Parser can generate fixture NATIVE_MODULE_WITH_PROMISE 'modules': { 'NativeSampleTurboModule': { 'type': 'NativeModule', - 'aliases': {}, + 'aliases': { + 'SomeObj': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'a', + 'optional': false, + 'typeAnnotation': { + 'type': 'StringTypeAnnotation' + } + } + ] + } + }, 'spec': { 'properties': [ { @@ -1515,7 +1528,10 @@ exports[`RN Codegen Flow Parser can generate fixture NATIVE_MODULE_WITH_PROMISE 'typeAnnotation': { 'type': 'FunctionTypeAnnotation', 'returnTypeAnnotation': { - 'type': 'PromiseTypeAnnotation' + 'type': 'PromiseTypeAnnotation', + 'elementType': { + 'type': 'StringTypeAnnotation' + } }, 'params': [] } @@ -1526,7 +1542,10 @@ exports[`RN Codegen Flow Parser can generate fixture NATIVE_MODULE_WITH_PROMISE 'typeAnnotation': { 'type': 'FunctionTypeAnnotation', 'returnTypeAnnotation': { - 'type': 'PromiseTypeAnnotation' + 'type': 'PromiseTypeAnnotation', + 'elementType': { + 'type': 'StringTypeAnnotation' + } }, 'params': [] } @@ -1537,7 +1556,11 @@ exports[`RN Codegen Flow Parser can generate fixture NATIVE_MODULE_WITH_PROMISE 'typeAnnotation': { 'type': 'FunctionTypeAnnotation', 'returnTypeAnnotation': { - 'type': 'PromiseTypeAnnotation' + 'type': 'PromiseTypeAnnotation', + 'elementType': { + 'type': 'TypeAliasTypeAnnotation', + 'name': 'SomeObj' + } }, 'params': [] } diff --git a/packages/react-native-codegen/src/parsers/typescript/modules/__tests__/__snapshots__/typescript-module-parser-snapshot-test.js.snap b/packages/react-native-codegen/src/parsers/typescript/modules/__tests__/__snapshots__/typescript-module-parser-snapshot-test.js.snap index c787dcbcbb0d..d49327021ef2 100644 --- a/packages/react-native-codegen/src/parsers/typescript/modules/__tests__/__snapshots__/typescript-module-parser-snapshot-test.js.snap +++ b/packages/react-native-codegen/src/parsers/typescript/modules/__tests__/__snapshots__/typescript-module-parser-snapshot-test.js.snap @@ -1713,7 +1713,20 @@ exports[`RN Codegen TypeScript Parser can generate fixture NATIVE_MODULE_WITH_PR 'modules': { 'NativeSampleTurboModule': { 'type': 'NativeModule', - 'aliases': {}, + 'aliases': { + 'SomeObj': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'a', + 'optional': false, + 'typeAnnotation': { + 'type': 'StringTypeAnnotation' + } + } + ] + } + }, 'spec': { 'properties': [ { @@ -1722,7 +1735,10 @@ exports[`RN Codegen TypeScript Parser can generate fixture NATIVE_MODULE_WITH_PR 'typeAnnotation': { 'type': 'FunctionTypeAnnotation', 'returnTypeAnnotation': { - 'type': 'PromiseTypeAnnotation' + 'type': 'PromiseTypeAnnotation', + 'elementType': { + 'type': 'StringTypeAnnotation' + } }, 'params': [] } @@ -1733,7 +1749,10 @@ exports[`RN Codegen TypeScript Parser can generate fixture NATIVE_MODULE_WITH_PR 'typeAnnotation': { 'type': 'FunctionTypeAnnotation', 'returnTypeAnnotation': { - 'type': 'PromiseTypeAnnotation' + 'type': 'PromiseTypeAnnotation', + 'elementType': { + 'type': 'StringTypeAnnotation' + } }, 'params': [] } @@ -1744,7 +1763,11 @@ exports[`RN Codegen TypeScript Parser can generate fixture NATIVE_MODULE_WITH_PR 'typeAnnotation': { 'type': 'FunctionTypeAnnotation', 'returnTypeAnnotation': { - 'type': 'PromiseTypeAnnotation' + 'type': 'PromiseTypeAnnotation', + 'elementType': { + 'type': 'TypeAliasTypeAnnotation', + 'name': 'SomeObj' + } }, 'params': [] } From 611ceb0407b41fc803abb882c1d2c4ff91ae3d65 Mon Sep 17 00:00:00 2001 From: "Zihan Chen (MSFT)" <53799235+ZihanChen-MSFT@users.noreply.github.com> Date: Mon, 14 Nov 2022 14:35:50 -0800 Subject: [PATCH 03/12] Fix unit test --- .../__tests__/parsers-primitives-test.js | 14 +++++++++ .../src/parsers/parsers-primitives.js | 29 ++++++++++++------- 2 files changed, 32 insertions(+), 11 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 082af17c1df3..0251851f74af 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 @@ -375,11 +375,18 @@ describe('emitPromise', () => { typeAnnotation, parser, nullable, + // mock translateTypeAnnotation function + undefined, + undefined, + undefined, + undefined, + (_,elementType)=>elementType, ); const expected = { type: 'NullableTypeAnnotation', typeAnnotation: { type: 'PromiseTypeAnnotation', + elementType:1, }, }; @@ -394,9 +401,16 @@ describe('emitPromise', () => { typeAnnotation, parser, nullable, + // mock translateTypeAnnotation function + undefined, + undefined, + undefined, + undefined, + (_,elementType)=>elementType, ); const expected = { type: 'PromiseTypeAnnotation', + elementType:1, }; expect(result).toEqual(expected); diff --git a/packages/react-native-codegen/src/parsers/parsers-primitives.js b/packages/react-native-codegen/src/parsers/parsers-primitives.js index a65e62569dc0..1e7ebbf24c91 100644 --- a/packages/react-native-codegen/src/parsers/parsers-primitives.js +++ b/packages/react-native-codegen/src/parsers/parsers-primitives.js @@ -198,17 +198,24 @@ function emitPromise( parser, ); - return wrapNullable(nullable, { - type: 'PromiseTypeAnnotation', - elementType: translateTypeAnnotation( - hasteModuleName, - typeAnnotation.typeParameters.params[0], - types, - aliasMap, - tryParse, - cxxOnly, - ), - }); + const elementType = typeAnnotation.typeParameters.params[0]; + if (elementType.type === 'ExistsTypeAnnotation') { + return wrapNullable(nullable, { + type: 'PromiseTypeAnnotation', + }); + } else { + return wrapNullable(nullable, { + type: 'PromiseTypeAnnotation', + elementType: translateTypeAnnotation( + hasteModuleName, + typeAnnotation.typeParameters.params[0], + types, + aliasMap, + tryParse, + cxxOnly, + ), + }); + } } function emitObject( From f979b1a600c928701e12b387ccefd5465cfc65a2 Mon Sep 17 00:00:00 2001 From: "Zihan Chen (MSFT)" <53799235+ZihanChen-MSFT@users.noreply.github.com> Date: Mon, 14 Nov 2022 14:36:45 -0800 Subject: [PATCH 04/12] yarn prettier --- .../src/parsers/__tests__/parsers-primitives-test.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 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 0251851f74af..f3b0c320b814 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 @@ -380,13 +380,13 @@ describe('emitPromise', () => { undefined, undefined, undefined, - (_,elementType)=>elementType, + (_, elementType) => elementType, ); const expected = { type: 'NullableTypeAnnotation', typeAnnotation: { type: 'PromiseTypeAnnotation', - elementType:1, + elementType: 1, }, }; @@ -406,11 +406,11 @@ describe('emitPromise', () => { undefined, undefined, undefined, - (_,elementType)=>elementType, + (_, elementType) => elementType, ); const expected = { type: 'PromiseTypeAnnotation', - elementType:1, + elementType: 1, }; expect(result).toEqual(expected); From 2b0dd2cc3e1049c8276114c1e9d8eedcd686af43 Mon Sep 17 00:00:00 2001 From: "Zihan Chen (MSFT)" <53799235+ZihanChen-MSFT@users.noreply.github.com> Date: Mon, 14 Nov 2022 14:54:35 -0800 Subject: [PATCH 05/12] yarn flow-check-ios --- .../react-native-codegen/src/CodegenSchema.js | 6 ++-- .../__tests__/parsers-primitives-test.js | 35 ++++++++++++++----- 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/packages/react-native-codegen/src/CodegenSchema.js b/packages/react-native-codegen/src/CodegenSchema.js index 3cb5e1fb26b4..fc96c5a372ef 100644 --- a/packages/react-native-codegen/src/CodegenSchema.js +++ b/packages/react-native-codegen/src/CodegenSchema.js @@ -297,9 +297,9 @@ export type NativeModuleTypeAliasTypeAnnotation = $ReadOnly<{ name: string, }>; -export type NativeModulePromiseTypeAnnotation = $ReadOnly<{ +export type NativeModulePromiseTypeAnnotation = $ReadOnly<{ type: 'PromiseTypeAnnotation', - elementType?: T, + elementType?: Nullable, }>; export type UnionTypeAnnotationMemberType = @@ -347,5 +347,5 @@ export type NativeModuleTypeAnnotation = type NativeModuleParamOnlyTypeAnnotation = NativeModuleFunctionTypeAnnotation; type NativeModuleReturnOnlyTypeAnnotation = - | NativeModulePromiseTypeAnnotation> + | NativeModulePromiseTypeAnnotation | VoidTypeAnnotation; 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 f3b0c320b814..39b81f8b73d9 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 @@ -351,7 +351,20 @@ describe('emitPromise', () => { it('throws an IncorrectlyParameterizedGenericParserError error', () => { const nullable = false; expect(() => - emitPromise(moduleName, typeAnnotation, parser, nullable), + emitPromise( + moduleName, + typeAnnotation, + parser, + nullable, + // mock translateTypeAnnotation function + {}, + {}, + function (_: () => T) { + return null; + }, + false, + (_, elementType) => elementType, + ), ).toThrow(); }); }); @@ -376,10 +389,12 @@ describe('emitPromise', () => { parser, nullable, // mock translateTypeAnnotation function - undefined, - undefined, - undefined, - undefined, + {}, + {}, + function (_: () => T) { + return null; + }, + false, (_, elementType) => elementType, ); const expected = { @@ -402,10 +417,12 @@ describe('emitPromise', () => { parser, nullable, // mock translateTypeAnnotation function - undefined, - undefined, - undefined, - undefined, + {}, + {}, + function (_: () => T) { + return null; + }, + false, (_, elementType) => elementType, ); const expected = { From 9d18099361d442b8ae819dff6c9f033061b66206 Mon Sep 17 00:00:00 2001 From: "Zihan Chen (MSFT)" <53799235+ZihanChen-MSFT@users.noreply.github.com> Date: Tue, 15 Nov 2022 12:29:37 -0800 Subject: [PATCH 06/12] Fix code review comments --- .../__tests__/parsers-primitives-test.js | 58 ++++++++----------- 1 file changed, 25 insertions(+), 33 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 39b81f8b73d9..827b805f82c7 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 @@ -338,6 +338,28 @@ describe('typeAliasResolution', () => { describe('emitPromise', () => { const moduleName = 'testModuleName'; + function emitPromiseForUnitTest(typeAnnotation: $FlowFixMe, nullable: boolean): $FlowFixMe { + return emitPromise( + moduleName, + typeAnnotation, + parser, + nullable, + // mock translateTypeAnnotation function + /* types: TypeDeclarationMap */ + {}, + /* aliasMap: {...NativeModuleAliasMap} */ + {}, + /* tryParse: ParserErrorCapturer */ + function (_: () => T) { + return null; + }, + /* cxxOnly: boolean */ + false, + /* the translateTypeAnnotation function */ + (_, elementType) => elementType, + ) + } + describe("when typeAnnotation doesn't have exactly one typeParameter", () => { const typeAnnotation = { typeParameters: { @@ -351,19 +373,9 @@ describe('emitPromise', () => { it('throws an IncorrectlyParameterizedGenericParserError error', () => { const nullable = false; expect(() => - emitPromise( - moduleName, + emitPromiseForUnitTest( typeAnnotation, - parser, nullable, - // mock translateTypeAnnotation function - {}, - {}, - function (_: () => T) { - return null; - }, - false, - (_, elementType) => elementType, ), ).toThrow(); }); @@ -383,19 +395,9 @@ describe('emitPromise', () => { describe('when nullable is true', () => { const nullable = true; it('returns nullable type annotation', () => { - const result = emitPromise( - moduleName, + const result = emitPromiseForUnitTest( typeAnnotation, - parser, nullable, - // mock translateTypeAnnotation function - {}, - {}, - function (_: () => T) { - return null; - }, - false, - (_, elementType) => elementType, ); const expected = { type: 'NullableTypeAnnotation', @@ -411,19 +413,9 @@ describe('emitPromise', () => { describe('when nullable is false', () => { const nullable = false; it('returns non nullable type annotation', () => { - const result = emitPromise( - moduleName, + const result = emitPromiseForUnitTest( typeAnnotation, - parser, nullable, - // mock translateTypeAnnotation function - {}, - {}, - function (_: () => T) { - return null; - }, - false, - (_, elementType) => elementType, ); const expected = { type: 'PromiseTypeAnnotation', From 77405c3b1ef05278a2db7ee0743703859b7aa138 Mon Sep 17 00:00:00 2001 From: "Zihan Chen (MSFT)" <53799235+ZihanChen-MSFT@users.noreply.github.com> Date: Tue, 15 Nov 2022 12:38:33 -0800 Subject: [PATCH 07/12] yarn prettier --- .../__tests__/parsers-primitives-test.js | 24 +++++++------------ 1 file changed, 8 insertions(+), 16 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 827b805f82c7..b55fa616a5f8 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 @@ -338,7 +338,10 @@ describe('typeAliasResolution', () => { describe('emitPromise', () => { const moduleName = 'testModuleName'; - function emitPromiseForUnitTest(typeAnnotation: $FlowFixMe, nullable: boolean): $FlowFixMe { + function emitPromiseForUnitTest( + typeAnnotation: $FlowFixMe, + nullable: boolean, + ): $FlowFixMe { return emitPromise( moduleName, typeAnnotation, @@ -357,7 +360,7 @@ describe('emitPromise', () => { false, /* the translateTypeAnnotation function */ (_, elementType) => elementType, - ) + ); } describe("when typeAnnotation doesn't have exactly one typeParameter", () => { @@ -372,12 +375,7 @@ describe('emitPromise', () => { }; it('throws an IncorrectlyParameterizedGenericParserError error', () => { const nullable = false; - expect(() => - emitPromiseForUnitTest( - typeAnnotation, - nullable, - ), - ).toThrow(); + expect(() => emitPromiseForUnitTest(typeAnnotation, nullable)).toThrow(); }); }); @@ -395,10 +393,7 @@ describe('emitPromise', () => { describe('when nullable is true', () => { const nullable = true; it('returns nullable type annotation', () => { - const result = emitPromiseForUnitTest( - typeAnnotation, - nullable, - ); + const result = emitPromiseForUnitTest(typeAnnotation, nullable); const expected = { type: 'NullableTypeAnnotation', typeAnnotation: { @@ -413,10 +408,7 @@ describe('emitPromise', () => { describe('when nullable is false', () => { const nullable = false; it('returns non nullable type annotation', () => { - const result = emitPromiseForUnitTest( - typeAnnotation, - nullable, - ); + const result = emitPromiseForUnitTest(typeAnnotation, nullable); const expected = { type: 'PromiseTypeAnnotation', elementType: 1, From e18f9a5067d1afbed55633e494344e533a25a345 Mon Sep 17 00:00:00 2001 From: "Zihan Chen (MSFT)" <53799235+ZihanChen-MSFT@users.noreply.github.com> Date: Fri, 18 Nov 2022 14:01:35 -0800 Subject: [PATCH 08/12] Add new Promise test --- .../__tests__/checkModuleSnaps-test.js | 2 +- .../modules/__test_fixtures__/fixtures.js | 28 ++++++ .../module-parser-snapshot-test.js.snap | 97 +++++++++++++++++++ .../src/parsers/parsers-primitives.js | 33 ++++--- 4 files changed, 147 insertions(+), 13 deletions(-) diff --git a/packages/react-native-codegen/src/parsers/consistency/__tests__/checkModuleSnaps-test.js b/packages/react-native-codegen/src/parsers/consistency/__tests__/checkModuleSnaps-test.js index 1e392b8dde6b..e14a6523156a 100644 --- a/packages/react-native-codegen/src/parsers/consistency/__tests__/checkModuleSnaps-test.js +++ b/packages/react-native-codegen/src/parsers/consistency/__tests__/checkModuleSnaps-test.js @@ -14,7 +14,7 @@ const {compareSnaps, compareTsArraySnaps} = require('../compareSnaps.js'); const flowFixtures = require('../../flow/modules/__test_fixtures__/fixtures.js'); const flowSnaps = require('../../../../src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap'); -const flowExtraCases = []; +const flowExtraCases = ['PROMISE_WITH_COMMONLY_USED_TYPES']; const tsFixtures = require('../../typescript/modules/__test_fixtures__/fixtures.js'); const tsSnaps = require('../../../../src/parsers/typescript/modules/__tests__/__snapshots__/typescript-module-parser-snapshot-test.js.snap'); const tsExtraCases = [ diff --git a/packages/react-native-codegen/src/parsers/flow/modules/__test_fixtures__/fixtures.js b/packages/react-native-codegen/src/parsers/flow/modules/__test_fixtures__/fixtures.js index 3b42068a003e..2a9b3f027243 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/__test_fixtures__/fixtures.js +++ b/packages/react-native-codegen/src/parsers/flow/modules/__test_fixtures__/fixtures.js @@ -682,6 +682,33 @@ export default TurboModuleRegistry.getEnforcing('SampleTurboModuleCxx'); `; +const PROMISE_WITH_COMMONLY_USED_TYPES = ` +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict-local + * @format + */ + +'use strict'; + +import type {TurboModule} from '../RCTExport'; +import * as TurboModuleRegistry from '../TurboModuleRegistry'; + +export interface Spec extends TurboModule { + returnStringArray(): Promise>; + returnObjectArray(): Promise>; + returnNullableNumber(): Promise; + returnEmpty(): Promise; + returnIndex(): Promise<{ [string]: 'authorized' | 'denied' | 'undetermined' | true | false }>; +} + +export default TurboModuleRegistry.getEnforcing('SampleTurboModule'); +`; + module.exports = { NATIVE_MODULE_WITH_OBJECT_WITH_OBJECT_DEFINED_IN_FILE_AS_PROPERTY, NATIVE_MODULE_WITH_ARRAY_WITH_UNION_AND_TOUPLE, @@ -705,4 +732,5 @@ module.exports = { ANDROID_ONLY_NATIVE_MODULE, IOS_ONLY_NATIVE_MODULE, CXX_ONLY_NATIVE_MODULE, + PROMISE_WITH_COMMONLY_USED_TYPES, }; diff --git a/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap b/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap index 8b5278ba4673..6734b279ed3c 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap +++ b/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap @@ -1750,3 +1750,100 @@ exports[`RN Codegen Flow Parser can generate fixture NATIVE_MODULE_WITH_UNSAFE_O } }" `; + +exports[`RN Codegen Flow Parser can generate fixture PROMISE_WITH_COMMONLY_USED_TYPES 1`] = ` +"{ + 'modules': { + 'NativeSampleTurboModule': { + 'type': 'NativeModule', + 'aliases': {}, + 'spec': { + 'properties': [ + { + 'name': 'returnStringArray', + 'optional': false, + 'typeAnnotation': { + 'type': 'FunctionTypeAnnotation', + 'returnTypeAnnotation': { + 'type': 'PromiseTypeAnnotation', + 'elementType': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'StringTypeAnnotation' + } + } + }, + 'params': [] + } + }, + { + 'name': 'returnObjectArray', + 'optional': false, + 'typeAnnotation': { + 'type': 'FunctionTypeAnnotation', + 'returnTypeAnnotation': { + 'type': 'PromiseTypeAnnotation', + 'elementType': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'GenericObjectTypeAnnotation' + } + } + }, + 'params': [] + } + }, + { + 'name': 'returnNullableNumber', + 'optional': false, + 'typeAnnotation': { + 'type': 'FunctionTypeAnnotation', + 'returnTypeAnnotation': { + 'type': 'PromiseTypeAnnotation' + }, + 'params': [] + } + }, + { + 'name': 'returnEmpty', + 'optional': false, + 'typeAnnotation': { + 'type': 'FunctionTypeAnnotation', + 'returnTypeAnnotation': { + 'type': 'PromiseTypeAnnotation' + }, + 'params': [] + } + }, + { + 'name': 'returnIndex', + 'optional': false, + 'typeAnnotation': { + 'type': 'FunctionTypeAnnotation', + 'returnTypeAnnotation': { + 'type': 'PromiseTypeAnnotation', + 'elementType': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'key', + 'optional': false, + 'typeAnnotation': { + 'type': 'GenericObjectTypeAnnotation' + } + } + ] + } + }, + 'params': [] + } + } + ] + }, + 'moduleNames': [ + 'SampleTurboModule' + ] + } + } +}" +`; diff --git a/packages/react-native-codegen/src/parsers/parsers-primitives.js b/packages/react-native-codegen/src/parsers/parsers-primitives.js index 1e7ebbf24c91..c6404dbfabb5 100644 --- a/packages/react-native-codegen/src/parsers/parsers-primitives.js +++ b/packages/react-native-codegen/src/parsers/parsers-primitives.js @@ -199,22 +199,31 @@ function emitPromise( ); const elementType = typeAnnotation.typeParameters.params[0]; - if (elementType.type === 'ExistsTypeAnnotation') { + if ( + elementType.type === 'ExistsTypeAnnotation' || + elementType.type === 'EmptyTypeAnnotation' + ) { return wrapNullable(nullable, { type: 'PromiseTypeAnnotation', }); } else { - return wrapNullable(nullable, { - type: 'PromiseTypeAnnotation', - elementType: translateTypeAnnotation( - hasteModuleName, - typeAnnotation.typeParameters.params[0], - types, - aliasMap, - tryParse, - cxxOnly, - ), - }); + try { + return wrapNullable(nullable, { + type: 'PromiseTypeAnnotation', + elementType: translateTypeAnnotation( + hasteModuleName, + typeAnnotation.typeParameters.params[0], + types, + aliasMap, + tryParse, + cxxOnly, + ), + }); + } catch { + return wrapNullable(nullable, { + type: 'PromiseTypeAnnotation', + }); + } } } From b0445f52e953b11c66500d3edcba03d0354c88f7 Mon Sep 17 00:00:00 2001 From: "Zihan Chen (MSFT)" <53799235+ZihanChen-MSFT@users.noreply.github.com> Date: Mon, 21 Nov 2022 22:47:55 -0800 Subject: [PATCH 09/12] Update test case --- .../flow/modules/__test_fixtures__/fixtures.js | 3 +++ .../module-parser-snapshot-test.js.snap | 15 +++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/packages/react-native-codegen/src/parsers/flow/modules/__test_fixtures__/fixtures.js b/packages/react-native-codegen/src/parsers/flow/modules/__test_fixtures__/fixtures.js index 2a9b3f027243..89545e47ed14 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/__test_fixtures__/fixtures.js +++ b/packages/react-native-codegen/src/parsers/flow/modules/__test_fixtures__/fixtures.js @@ -698,12 +698,15 @@ const PROMISE_WITH_COMMONLY_USED_TYPES = ` import type {TurboModule} from '../RCTExport'; import * as TurboModuleRegistry from '../TurboModuleRegistry'; +export type Season = 'Spring' | 'Summer' | 'Autumn' | 'Winter'; + export interface Spec extends TurboModule { returnStringArray(): Promise>; returnObjectArray(): Promise>; returnNullableNumber(): Promise; returnEmpty(): Promise; returnIndex(): Promise<{ [string]: 'authorized' | 'denied' | 'undetermined' | true | false }>; + returnEnum() : Promise; } export default TurboModuleRegistry.getEnforcing('SampleTurboModule'); diff --git a/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap b/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap index 6734b279ed3c..624980589df2 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap +++ b/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap @@ -1837,6 +1837,21 @@ exports[`RN Codegen Flow Parser can generate fixture PROMISE_WITH_COMMONLY_USED_ }, 'params': [] } + }, + { + 'name': 'returnEnum', + 'optional': false, + 'typeAnnotation': { + 'type': 'FunctionTypeAnnotation', + 'returnTypeAnnotation': { + 'type': 'PromiseTypeAnnotation', + 'elementType': { + 'type': 'UnionTypeAnnotation', + 'memberType': 'StringTypeAnnotation' + } + }, + 'params': [] + } } ] }, From 062e86455e4a4c45cac54e533beb98d1376a6d03 Mon Sep 17 00:00:00 2001 From: "Zihan Chen (MSFT)" <53799235+ZihanChen-MSFT@users.noreply.github.com> Date: Sun, 27 Nov 2022 22:55:25 -0800 Subject: [PATCH 10/12] Add more promise test case --- .../parsers/flow/modules/__test_fixtures__/fixtures.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/react-native-codegen/src/parsers/flow/modules/__test_fixtures__/fixtures.js b/packages/react-native-codegen/src/parsers/flow/modules/__test_fixtures__/fixtures.js index 89545e47ed14..904ca7d5d426 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/__test_fixtures__/fixtures.js +++ b/packages/react-native-codegen/src/parsers/flow/modules/__test_fixtures__/fixtures.js @@ -700,6 +700,13 @@ import * as TurboModuleRegistry from '../TurboModuleRegistry'; export type Season = 'Spring' | 'Summer' | 'Autumn' | 'Winter'; +export type CustomObject = {| + field1: Array, + field2: boolean, + field3: string, + type: 'A_String_Literal', +|}; + export interface Spec extends TurboModule { returnStringArray(): Promise>; returnObjectArray(): Promise>; @@ -707,6 +714,7 @@ export interface Spec extends TurboModule { returnEmpty(): Promise; returnIndex(): Promise<{ [string]: 'authorized' | 'denied' | 'undetermined' | true | false }>; returnEnum() : Promise; + returnObject() : Promise; } export default TurboModuleRegistry.getEnforcing('SampleTurboModule'); From 0e53ebe2c9a8641d2075834c65d4be60be3a9aa8 Mon Sep 17 00:00:00 2001 From: "Zihan Chen (MSFT)" <53799235+ZihanChen-MSFT@users.noreply.github.com> Date: Sun, 27 Nov 2022 23:05:37 -0800 Subject: [PATCH 11/12] ... --- .../module-parser-snapshot-test.js.snap | 55 ++++++++++++++++++- .../src/parsers/flow/modules/index.js | 7 +++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap b/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap index 624980589df2..c8c143c5cfda 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap +++ b/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap @@ -1756,7 +1756,45 @@ exports[`RN Codegen Flow Parser can generate fixture PROMISE_WITH_COMMONLY_USED_ 'modules': { 'NativeSampleTurboModule': { 'type': 'NativeModule', - 'aliases': {}, + 'aliases': { + 'CustomObject': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'field1', + 'optional': false, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'GenericObjectTypeAnnotation' + } + } + }, + { + 'name': 'field2', + 'optional': false, + 'typeAnnotation': { + 'type': 'BooleanTypeAnnotation' + } + }, + { + 'name': 'field3', + 'optional': false, + 'typeAnnotation': { + 'type': 'StringTypeAnnotation' + } + }, + { + 'name': 'type', + 'optional': false, + 'typeAnnotation': { + 'type': 'UnionTypeAnnotation', + 'memberType': 'StringTypeAnnotation' + } + } + ] + } + }, 'spec': { 'properties': [ { @@ -1852,6 +1890,21 @@ exports[`RN Codegen Flow Parser can generate fixture PROMISE_WITH_COMMONLY_USED_ }, 'params': [] } + }, + { + 'name': 'returnObject', + 'optional': false, + 'typeAnnotation': { + 'type': 'FunctionTypeAnnotation', + 'returnTypeAnnotation': { + 'type': 'PromiseTypeAnnotation', + 'elementType': { + 'type': 'TypeAliasTypeAnnotation', + 'name': 'CustomObject' + } + }, + 'params': [] + } } ] }, 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 6b1155106722..13d7b26d9d97 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/index.js +++ b/packages/react-native-codegen/src/parsers/flow/modules/index.js @@ -295,6 +295,13 @@ function translateTypeAnnotation( parser, ); } + case 'StringLiteralTypeAnnotation': { + // 'a' is a special case for 'a' | 'b' because the type name is different + return wrapNullable(nullable, { + type: 'UnionTypeAnnotation', + memberType: 'StringTypeAnnotation' + }); + } case 'MixedTypeAnnotation': { if (cxxOnly) { return emitMixedTypeAnnotation(nullable); From c3a65c0cdb25704703fbc22528b32d901081f61c Mon Sep 17 00:00:00 2001 From: "Zihan Chen (MSFT)" <53799235+ZihanChen-MSFT@users.noreply.github.com> Date: Sun, 27 Nov 2022 23:07:14 -0800 Subject: [PATCH 12/12] ... --- .../react-native-codegen/src/parsers/flow/modules/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 13d7b26d9d97..9c0b44d9396a 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/index.js +++ b/packages/react-native-codegen/src/parsers/flow/modules/index.js @@ -296,10 +296,10 @@ function translateTypeAnnotation( ); } case 'StringLiteralTypeAnnotation': { - // 'a' is a special case for 'a' | 'b' because the type name is different + // 'a' is a special case for 'a' | 'b' but the type name is different return wrapNullable(nullable, { type: 'UnionTypeAnnotation', - memberType: 'StringTypeAnnotation' + memberType: 'StringTypeAnnotation', }); } case 'MixedTypeAnnotation': {