From 52b2fc499b4c55baa67d0e22b2cf4423069af2e3 Mon Sep 17 00:00:00 2001 From: "Zihan Chen (MSFT)" <53799235+ZihanChen-MSFT@users.noreply.github.com> Date: Mon, 7 Nov 2022 11:14:44 -0800 Subject: [PATCH 01/11] Add test cases for TSIntersectionType --- .../__tests__/checkComponentSnaps-test.js | 2 +- .../components/__test_fixtures__/fixtures.js | 10 ++++ .../typescript-component-parser-test.js.snap | 46 +++++++++++++++++++ 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/packages/react-native-codegen/src/parsers/consistency/__tests__/checkComponentSnaps-test.js b/packages/react-native-codegen/src/parsers/consistency/__tests__/checkComponentSnaps-test.js index c1088b1f0b0c..b06dd17789c9 100644 --- a/packages/react-native-codegen/src/parsers/consistency/__tests__/checkComponentSnaps-test.js +++ b/packages/react-native-codegen/src/parsers/consistency/__tests__/checkComponentSnaps-test.js @@ -21,7 +21,7 @@ const tsExtraCases = [ 'ARRAY2_PROP_TYPES_NO_EVENTS', 'PROPS_AND_EVENTS_WITH_INTERFACES', ]; -const ignoredCases = ['ARRAY_PROP_TYPES_NO_EVENTS']; +const ignoredCases = []; compareSnaps( flowFixtures, diff --git a/packages/react-native-codegen/src/parsers/typescript/components/__test_fixtures__/fixtures.js b/packages/react-native-codegen/src/parsers/typescript/components/__test_fixtures__/fixtures.js index 4005574ba68d..0b15b6cf334f 100644 --- a/packages/react-native-codegen/src/parsers/typescript/components/__test_fixtures__/fixtures.js +++ b/packages/react-native-codegen/src/parsers/typescript/components/__test_fixtures__/fixtures.js @@ -452,6 +452,13 @@ export interface ModuleProps extends ViewProps { array_of_array_of_object_required_in_file: ReadonlyArray< ReadonlyArray >; + + // Nested array of array of object types (with spread) + array_of_array_of_object_required_with_spread: ReadonlyArray< + ReadonlyArray< + Readonly, + >, + >, } export default codegenNativeComponent( @@ -584,6 +591,9 @@ export interface ModuleProps extends ViewProps { // Nested array of array of object types (in file) array_of_array_of_object_required_in_file: readonly ObjectType[][]; + + // Nested array of array of object types (with spread) + array_of_array_of_object_required_with_spread: readonly Readonly[][]; } export default codegenNativeComponent( diff --git a/packages/react-native-codegen/src/parsers/typescript/components/__tests__/__snapshots__/typescript-component-parser-test.js.snap b/packages/react-native-codegen/src/parsers/typescript/components/__tests__/__snapshots__/typescript-component-parser-test.js.snap index 90947e1af64d..9a31424cba2a 100644 --- a/packages/react-native-codegen/src/parsers/typescript/components/__tests__/__snapshots__/typescript-component-parser-test.js.snap +++ b/packages/react-native-codegen/src/parsers/typescript/components/__tests__/__snapshots__/typescript-component-parser-test.js.snap @@ -1221,6 +1221,29 @@ exports[`RN Codegen TypeScript Parser can generate fixture ARRAY_PROP_TYPES_NO_E } } } + }, + { + 'name': 'array_of_array_of_object_required_with_spread', + 'optional': false, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': false, + 'typeAnnotation': { + 'type': 'StringTypeAnnotation', + 'default': null + } + } + ] + } + } + } } ], 'commands': [] @@ -1905,6 +1928,29 @@ exports[`RN Codegen TypeScript Parser can generate fixture ARRAY2_PROP_TYPES_NO_ } } } + }, + { + 'name': 'array_of_array_of_object_required_with_spread', + 'optional': false, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': false, + 'typeAnnotation': { + 'type': 'StringTypeAnnotation', + 'default': null + } + } + ] + } + } + } } ], 'commands': [] From 4282acf1bc160a91c82680055f718204444483c3 Mon Sep 17 00:00:00 2001 From: "Zihan Chen (MSFT)" <53799235+ZihanChen-MSFT@users.noreply.github.com> Date: Mon, 7 Nov 2022 11:32:19 -0800 Subject: [PATCH 02/11] Begin extract getCommonTypeAnnotation --- .../typescript/components/componentsUtils.js | 70 ++++++++++--------- 1 file changed, 38 insertions(+), 32 deletions(-) diff --git a/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js b/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js index 0d84786df8f2..cbc74cd65e28 100644 --- a/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js +++ b/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js @@ -163,6 +163,34 @@ function detectArrayType( return null; } +function getCommonTypeAnnotation( + type: string, + typeAnnotation: $FlowFixMe, + types: TypeDeclarationMap, + buildSchema: (property: PropAST, types: TypeDeclarationMap) => ?NamedShape, +): $FlowFixMe { + switch (type) { + case 'TSTypeLiteral': + case 'TSInterfaceDeclaration': { + const rawProperties = + type === 'TSInterfaceDeclaration' + ? [typeAnnotation] + : typeAnnotation.members; + const flattenedProperties = flattenProperties(rawProperties, types); + const properties = flattenedProperties + .map(prop => buildSchema(prop, types)) + .filter(Boolean); + + return { + type: 'ObjectTypeAnnotation', + properties, + }; + } + default: + return undefined; + } +} + function getTypeAnnotationForArray( name: string, typeAnnotation: $FlowFixMe, @@ -207,23 +235,12 @@ function getTypeAnnotationForArray( extractedTypeAnnotation.typeName?.name || extractedTypeAnnotation.type; + const common = getCommonTypeAnnotation(type, extractedTypeAnnotation, types, buildSchema); + if (common) { + return common; + } + switch (type) { - case 'TSTypeLiteral': - case 'TSInterfaceDeclaration': { - const rawProperties = - type === 'TSInterfaceDeclaration' - ? [extractedTypeAnnotation] - : extractedTypeAnnotation.members; - if (rawProperties === undefined) { - throw new Error(type); - } - return { - type: 'ObjectTypeAnnotation', - properties: flattenProperties(rawProperties, types) - .map(prop => buildSchema(prop, types)) - .filter(Boolean), - }; - } case 'TSNumberKeyword': return { type: 'FloatTypeAnnotation', @@ -319,23 +336,12 @@ function getTypeAnnotation( ? typeAnnotation.typeName.name : typeAnnotation.type; - switch (type) { - case 'TSTypeLiteral': - case 'TSInterfaceDeclaration': { - const rawProperties = - type === 'TSInterfaceDeclaration' - ? [typeAnnotation] - : typeAnnotation.members; - const flattenedProperties = flattenProperties(rawProperties, types); - const properties = flattenedProperties - .map(prop => buildSchema(prop, types)) - .filter(Boolean); + const common = getCommonTypeAnnotation(type, typeAnnotation, types, buildSchema); + if (common) { + return common; + } - return { - type: 'ObjectTypeAnnotation', - properties, - }; - } + switch (type) { case 'ImageSource': return { type: 'ReservedPropTypeAnnotation', From 96a0886769507982ca07e1b1f2a0ef77e9eab425 Mon Sep 17 00:00:00 2001 From: "Zihan Chen (MSFT)" <53799235+ZihanChen-MSFT@users.noreply.github.com> Date: Mon, 7 Nov 2022 11:36:38 -0800 Subject: [PATCH 03/11] ... --- .../typescript/components/componentsUtils.js | 78 +++++++------------ 1 file changed, 26 insertions(+), 52 deletions(-) diff --git a/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js b/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js index cbc74cd65e28..e5be28d17ce6 100644 --- a/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js +++ b/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js @@ -186,6 +186,32 @@ function getCommonTypeAnnotation( properties, }; } + case 'ImageSource': + return { + type: 'ReservedPropTypeAnnotation', + name: 'ImageSourcePrimitive', + }; + case 'ImageRequest': + return { + type: 'ReservedPropTypeAnnotation', + name: 'ImageRequestPrimitive', + }; + case 'ColorValue': + case 'ProcessedColorValue': + return { + type: 'ReservedPropTypeAnnotation', + name: 'ColorPrimitive', + }; + case 'PointValue': + return { + type: 'ReservedPropTypeAnnotation', + name: 'PointPrimitive', + }; + case 'EdgeInsetsValue': + return { + type: 'ReservedPropTypeAnnotation', + name: 'EdgeInsetsPrimitive', + }; default: return undefined; } @@ -245,32 +271,6 @@ function getTypeAnnotationForArray( return { type: 'FloatTypeAnnotation', }; - case 'ImageSource': - return { - type: 'ReservedPropTypeAnnotation', - name: 'ImageSourcePrimitive', - }; - case 'ImageRequest': - return { - type: 'ReservedPropTypeAnnotation', - name: 'ImageRequestPrimitive', - }; - case 'ColorValue': - case 'ProcessedColorValue': - return { - type: 'ReservedPropTypeAnnotation', - name: 'ColorPrimitive', - }; - case 'PointValue': - return { - type: 'ReservedPropTypeAnnotation', - name: 'PointPrimitive', - }; - case 'EdgeInsetsValue': - return { - type: 'ReservedPropTypeAnnotation', - name: 'EdgeInsetsPrimitive', - }; case 'Stringish': return { type: 'StringTypeAnnotation', @@ -342,22 +342,6 @@ function getTypeAnnotation( } switch (type) { - case 'ImageSource': - return { - type: 'ReservedPropTypeAnnotation', - name: 'ImageSourcePrimitive', - }; - case 'ImageRequest': - return { - type: 'ReservedPropTypeAnnotation', - name: 'ImageRequestPrimitive', - }; - case 'ColorValue': - case 'ProcessedColorValue': - return { - type: 'ReservedPropTypeAnnotation', - name: 'ColorPrimitive', - }; case 'ColorArrayValue': return { type: 'ArrayTypeAnnotation', @@ -366,16 +350,6 @@ function getTypeAnnotation( name: 'ColorPrimitive', }, }; - case 'PointValue': - return { - type: 'ReservedPropTypeAnnotation', - name: 'PointPrimitive', - }; - case 'EdgeInsetsValue': - return { - type: 'ReservedPropTypeAnnotation', - name: 'EdgeInsetsPrimitive', - }; case 'Int32': return { type: 'Int32TypeAnnotation', From 8d06187173078635a6d278acb19e759ca68b4804 Mon Sep 17 00:00:00 2001 From: "Zihan Chen (MSFT)" <53799235+ZihanChen-MSFT@users.noreply.github.com> Date: Mon, 7 Nov 2022 11:41:08 -0800 Subject: [PATCH 04/11] ... --- .../typescript/components/componentsUtils.js | 31 ++++++++----------- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js b/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js index e5be28d17ce6..8ac05d093222 100644 --- a/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js +++ b/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js @@ -164,8 +164,11 @@ function detectArrayType( } function getCommonTypeAnnotation( + name: string, + forArray: boolean, type: string, typeAnnotation: $FlowFixMe, + defaultValue: $FlowFixMe | void, types: TypeDeclarationMap, buildSchema: (property: PropAST, types: TypeDeclarationMap) => ?NamedShape, ): $FlowFixMe { @@ -212,6 +215,14 @@ function getCommonTypeAnnotation( type: 'ReservedPropTypeAnnotation', name: 'EdgeInsetsPrimitive', }; + case 'TSUnionType': + return getUnionOfLiterals( + name, + forArray, + typeAnnotation.types, + defaultValue, + types, + ); default: return undefined; } @@ -261,7 +272,7 @@ function getTypeAnnotationForArray( extractedTypeAnnotation.typeName?.name || extractedTypeAnnotation.type; - const common = getCommonTypeAnnotation(type, extractedTypeAnnotation, types, buildSchema); + const common = getCommonTypeAnnotation(name, true, type, extractedTypeAnnotation, defaultValue, types, buildSchema); if (common) { return common; } @@ -295,14 +306,6 @@ function getTypeAnnotationForArray( return { type: 'StringTypeAnnotation', }; - case 'TSUnionType': - return getUnionOfLiterals( - name, - true, - extractedTypeAnnotation.types, - defaultValue, - types, - ); default: (type: empty); throw new Error(`Unknown prop type for "${name}": ${type}`); @@ -336,7 +339,7 @@ function getTypeAnnotation( ? typeAnnotation.typeName.name : typeAnnotation.type; - const common = getCommonTypeAnnotation(type, typeAnnotation, types, buildSchema); + const common = getCommonTypeAnnotation(name, false, type, typeAnnotation, defaultValue, types, buildSchema); if (common) { return common; } @@ -392,14 +395,6 @@ function getTypeAnnotation( throw new Error( `Cannot use "${type}" type annotation for "${name}": must use a specific numeric type like Int32, Double, or Float`, ); - case 'TSUnionType': - return getUnionOfLiterals( - name, - false, - typeAnnotation.types, - defaultValue, - types, - ); default: (type: empty); throw new Error(`Unknown prop type for "${name}": "${type}"`); From 4dc5bff3a566f794ef6958df0f0a5b1b7416ef21 Mon Sep 17 00:00:00 2001 From: "Zihan Chen (MSFT)" <53799235+ZihanChen-MSFT@users.noreply.github.com> Date: Mon, 7 Nov 2022 11:51:53 -0800 Subject: [PATCH 05/11] ... --- .../typescript/components/componentsUtils.js | 106 ++++++++---------- 1 file changed, 44 insertions(+), 62 deletions(-) diff --git a/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js b/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js index 8ac05d093222..e50fefee0041 100644 --- a/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js +++ b/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js @@ -223,6 +223,27 @@ function getCommonTypeAnnotation( defaultValue, types, ); + case 'Int32': + return { + type: 'Int32TypeAnnotation', + }; + case 'Double': + return { + type: 'DoubleTypeAnnotation', + }; + case 'Float': + return { + type: 'FloatTypeAnnotation', + }; + case 'TSBooleanKeyword': + return { + type: 'BooleanTypeAnnotation', + }; + case 'Stringish': + case 'TSStringKeyword': + return { + type: 'StringTypeAnnotation', + }; default: return undefined; } @@ -282,30 +303,6 @@ function getTypeAnnotationForArray( return { type: 'FloatTypeAnnotation', }; - case 'Stringish': - return { - type: 'StringTypeAnnotation', - }; - case 'Int32': - return { - type: 'Int32TypeAnnotation', - }; - case 'Double': - return { - type: 'DoubleTypeAnnotation', - }; - case 'Float': - return { - type: 'FloatTypeAnnotation', - }; - case 'TSBooleanKeyword': - return { - type: 'BooleanTypeAnnotation', - }; - case 'TSStringKeyword': - return { - type: 'StringTypeAnnotation', - }; default: (type: empty); throw new Error(`Unknown prop type for "${name}": ${type}`); @@ -341,6 +338,29 @@ function getTypeAnnotation( const common = getCommonTypeAnnotation(name, false, type, typeAnnotation, defaultValue, types, buildSchema); if (common) { + switch (common.type) { + case 'Int32TypeAnnotation': + common.default = ((defaultValue ? defaultValue : 0): number); + break; + case 'DoubleTypeAnnotation': + common.default = ((defaultValue ? defaultValue : 0): number); + break; + case 'FloatTypeAnnotation': + common.default = ((defaultValue === null + ? null + : defaultValue + ? defaultValue + : 0): number | null); + break; + case 'BooleanTypeAnnotation': + common.default = (defaultValue === null ? null : !!defaultValue); + break; + case 'StringTypeAnnotation': + common.default = ((defaultValue === undefined ? null : defaultValue): + | string + | null); + break; + } return common; } @@ -353,44 +373,6 @@ function getTypeAnnotation( name: 'ColorPrimitive', }, }; - case 'Int32': - return { - type: 'Int32TypeAnnotation', - default: ((defaultValue ? defaultValue : 0): number), - }; - case 'Double': - return { - type: 'DoubleTypeAnnotation', - default: ((defaultValue ? defaultValue : 0): number), - }; - case 'Float': - return { - type: 'FloatTypeAnnotation', - default: ((defaultValue === null - ? null - : defaultValue - ? defaultValue - : 0): number | null), - }; - case 'TSBooleanKeyword': - return { - type: 'BooleanTypeAnnotation', - default: defaultValue === null ? null : !!defaultValue, - }; - case 'TSStringKeyword': - return { - type: 'StringTypeAnnotation', - default: ((defaultValue === undefined ? null : defaultValue): - | string - | null), - }; - case 'Stringish': - return { - type: 'StringTypeAnnotation', - default: ((defaultValue === undefined ? null : defaultValue): - | string - | null), - }; case 'TSNumberKeyword': throw new Error( `Cannot use "${type}" type annotation for "${name}": must use a specific numeric type like Int32, Double, or Float`, From 17753c4a3d56176220ddeb95eb62af34508517d8 Mon Sep 17 00:00:00 2001 From: "Zihan Chen (MSFT)" <53799235+ZihanChen-MSFT@users.noreply.github.com> Date: Mon, 7 Nov 2022 11:55:04 -0800 Subject: [PATCH 06/11] yarn prettier --- .../typescript/components/componentsUtils.js | 30 ++++++++++++++----- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js b/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js index e50fefee0041..976fac293720 100644 --- a/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js +++ b/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js @@ -293,7 +293,15 @@ function getTypeAnnotationForArray( extractedTypeAnnotation.typeName?.name || extractedTypeAnnotation.type; - const common = getCommonTypeAnnotation(name, true, type, extractedTypeAnnotation, defaultValue, types, buildSchema); + const common = getCommonTypeAnnotation( + name, + true, + type, + extractedTypeAnnotation, + defaultValue, + types, + buildSchema, + ); if (common) { return common; } @@ -336,12 +344,18 @@ function getTypeAnnotation( ? typeAnnotation.typeName.name : typeAnnotation.type; - const common = getCommonTypeAnnotation(name, false, type, typeAnnotation, defaultValue, types, buildSchema); + const common = getCommonTypeAnnotation( + name, + false, + type, + typeAnnotation, + defaultValue, + types, + buildSchema, + ); if (common) { switch (common.type) { case 'Int32TypeAnnotation': - common.default = ((defaultValue ? defaultValue : 0): number); - break; case 'DoubleTypeAnnotation': common.default = ((defaultValue ? defaultValue : 0): number); break; @@ -351,14 +365,14 @@ function getTypeAnnotation( : defaultValue ? defaultValue : 0): number | null); - break; + break; case 'BooleanTypeAnnotation': - common.default = (defaultValue === null ? null : !!defaultValue); + common.default = defaultValue === null ? null : !!defaultValue; break; case 'StringTypeAnnotation': common.default = ((defaultValue === undefined ? null : defaultValue): - | string - | null); + | string + | null); break; } return common; From 62cb0feb960a4dd719cdf4fd3c6c6e7aff50cb5f Mon Sep 17 00:00:00 2001 From: "Zihan Chen (MSFT)" <53799235+ZihanChen-MSFT@users.noreply.github.com> Date: Mon, 7 Nov 2022 12:16:59 -0800 Subject: [PATCH 07/11] Handle TSIntersectionType --- .../typescript/components/componentsUtils.js | 13 +++-- .../parsers/typescript/parseTopLevelType.js | 52 +++++++++++++++++++ 2 files changed, 60 insertions(+), 5 deletions(-) diff --git a/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js b/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js index 976fac293720..092c9899a98c 100644 --- a/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js +++ b/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js @@ -11,7 +11,7 @@ 'use strict'; import type {ASTNode} from '../utils'; import type {NamedShape} from '../../../CodegenSchema.js'; -const {parseTopLevelType} = require('../parseTopLevelType'); +const {parseTopLevelType, flattenIntersectionType} = require('../parseTopLevelType'); import type {TypeDeclarationMap} from '../../utils'; function getProperties( @@ -174,11 +174,12 @@ function getCommonTypeAnnotation( ): $FlowFixMe { switch (type) { case 'TSTypeLiteral': - case 'TSInterfaceDeclaration': { + case 'TSInterfaceDeclaration': + case 'TSIntersectionType': { const rawProperties = - type === 'TSInterfaceDeclaration' - ? [typeAnnotation] - : typeAnnotation.members; + type === 'TSInterfaceDeclaration' ? [typeAnnotation]: + type === 'TSIntersectionType' ? flattenIntersectionType(typeAnnotation, types) : + typeAnnotation.members; const flattenedProperties = flattenProperties(rawProperties, types); const properties = flattenedProperties .map(prop => buildSchema(prop, types)) @@ -469,6 +470,8 @@ function flattenProperties( return flattenProperties(property.members, types); } else if (property.type === 'TSInterfaceDeclaration') { return flattenProperties(getProperties(property.id.name, types), types); + } else if (property.type === 'TSIntersectionType') { + return flattenProperties(property.types, types); } else { throw new Error( `${property.type} is not a supported object literal type.`, diff --git a/packages/react-native-codegen/src/parsers/typescript/parseTopLevelType.js b/packages/react-native-codegen/src/parsers/typescript/parseTopLevelType.js index 8ec8580e66c9..2a79c962506a 100644 --- a/packages/react-native-codegen/src/parsers/typescript/parseTopLevelType.js +++ b/packages/react-native-codegen/src/parsers/typescript/parseTopLevelType.js @@ -184,6 +184,58 @@ function parseTopLevelType( } } +function handleIntersectionAndParen( + type: $FlowFixMe, + result: Array<$FlowFixMe>, + knownTypes?: TypeDeclarationMap, +): void { + switch (type.type) { + case 'TSParenthesizedType': { + handleIntersectionAndParen(type.typeAnnotation, result, knownTypes); + break; + } + case 'TSIntersectionType': { + for (const t of type.types) { + handleIntersectionAndParen(t, result, knownTypes); + } + break; + } + case 'TSTypeReference': + if (type.typeName.name === 'Readonly') { + handleIntersectionAndParen(type.typeParameters.params[0], result, knownTypes); + } else if (type.typeName.name === 'WithDefault') { + throw new Error( + 'WithDefault<> is now allowed in intersection types.', + ); + } else if (!knownTypes) { + result.push(type); + } else { + const resolvedType = getValueFromTypes(type, knownTypes); + if ( + resolvedType.type === 'TSTypeReference' && + resolvedType.typeName.name === type.typeName.name + ) { + result.push(type); + } else { + handleIntersectionAndParen(resolvedType, result, knownTypes); + } + } + break; + default: + result.push(type); + } +} + +function flattenIntersectionType( + type: $FlowFixMe, + knownTypes?: TypeDeclarationMap, +): Array<$FlowFixMe> { + const result: Array<$FlowFixMe> = []; + handleIntersectionAndParen(type, result, knownTypes); + return result; +} + module.exports = { parseTopLevelType, + flattenIntersectionType, }; From df4d3dbd23ddfb8031aaac992858df08f3b6959e Mon Sep 17 00:00:00 2001 From: "Zihan Chen (MSFT)" <53799235+ZihanChen-MSFT@users.noreply.github.com> Date: Mon, 7 Nov 2022 12:18:24 -0800 Subject: [PATCH 08/11] yarn prettier --- .../typescript/components/componentsUtils.js | 13 +++++++++---- .../src/parsers/typescript/parseTopLevelType.js | 10 ++++++---- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js b/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js index 092c9899a98c..63ce01f3c7f2 100644 --- a/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js +++ b/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js @@ -11,7 +11,10 @@ 'use strict'; import type {ASTNode} from '../utils'; import type {NamedShape} from '../../../CodegenSchema.js'; -const {parseTopLevelType, flattenIntersectionType} = require('../parseTopLevelType'); +const { + parseTopLevelType, + flattenIntersectionType, +} = require('../parseTopLevelType'); import type {TypeDeclarationMap} from '../../utils'; function getProperties( @@ -177,9 +180,11 @@ function getCommonTypeAnnotation( case 'TSInterfaceDeclaration': case 'TSIntersectionType': { const rawProperties = - type === 'TSInterfaceDeclaration' ? [typeAnnotation]: - type === 'TSIntersectionType' ? flattenIntersectionType(typeAnnotation, types) : - typeAnnotation.members; + type === 'TSInterfaceDeclaration' + ? [typeAnnotation] + : type === 'TSIntersectionType' + ? flattenIntersectionType(typeAnnotation, types) + : typeAnnotation.members; const flattenedProperties = flattenProperties(rawProperties, types); const properties = flattenedProperties .map(prop => buildSchema(prop, types)) diff --git a/packages/react-native-codegen/src/parsers/typescript/parseTopLevelType.js b/packages/react-native-codegen/src/parsers/typescript/parseTopLevelType.js index 2a79c962506a..79b7ed30ebb6 100644 --- a/packages/react-native-codegen/src/parsers/typescript/parseTopLevelType.js +++ b/packages/react-native-codegen/src/parsers/typescript/parseTopLevelType.js @@ -202,11 +202,13 @@ function handleIntersectionAndParen( } case 'TSTypeReference': if (type.typeName.name === 'Readonly') { - handleIntersectionAndParen(type.typeParameters.params[0], result, knownTypes); - } else if (type.typeName.name === 'WithDefault') { - throw new Error( - 'WithDefault<> is now allowed in intersection types.', + handleIntersectionAndParen( + type.typeParameters.params[0], + result, + knownTypes, ); + } else if (type.typeName.name === 'WithDefault') { + throw new Error('WithDefault<> is now allowed in intersection types.'); } else if (!knownTypes) { result.push(type); } else { From bb1aec31daeddc796bfe8e25556cb44743860682 Mon Sep 17 00:00:00 2001 From: "Zihan Chen (MSFT)" <53799235+ZihanChen-MSFT@users.noreply.github.com> Date: Tue, 8 Nov 2022 14:42:48 -0800 Subject: [PATCH 09/11] Fix code review comments --- .../typescript/components/componentsUtils.js | 37 ++++++++++--------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js b/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js index 63ce01f3c7f2..5ac4978bb885 100644 --- a/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js +++ b/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js @@ -166,6 +166,22 @@ function detectArrayType( return null; } +function buildObjectType( + rawProperties: Array<$FlowFixMe>, + types: TypeDeclarationMap, + buildSchema: (property: PropAST, types: TypeDeclarationMap) => ?NamedShape, +): $FlowFixMe { + const flattenedProperties = flattenProperties(rawProperties, types); + const properties = flattenedProperties + .map(prop => buildSchema(prop, types)) + .filter(Boolean); + + return { + type: 'ObjectTypeAnnotation', + properties, + }; +} + function getCommonTypeAnnotation( name: string, forArray: boolean, @@ -177,24 +193,11 @@ function getCommonTypeAnnotation( ): $FlowFixMe { switch (type) { case 'TSTypeLiteral': + return buildObjectType(typeAnnotation.members, types, buildSchema); case 'TSInterfaceDeclaration': - case 'TSIntersectionType': { - const rawProperties = - type === 'TSInterfaceDeclaration' - ? [typeAnnotation] - : type === 'TSIntersectionType' - ? flattenIntersectionType(typeAnnotation, types) - : typeAnnotation.members; - const flattenedProperties = flattenProperties(rawProperties, types); - const properties = flattenedProperties - .map(prop => buildSchema(prop, types)) - .filter(Boolean); - - return { - type: 'ObjectTypeAnnotation', - properties, - }; - } + return buildObjectType([typeAnnotation], types, buildSchema); + case 'TSIntersectionType': + return buildObjectType(flattenIntersectionType(typeAnnotation, types), types, buildSchema); case 'ImageSource': return { type: 'ReservedPropTypeAnnotation', From 2393651a812c54478ef021dfc5ccfac180eeb3e9 Mon Sep 17 00:00:00 2001 From: "Zihan Chen (MSFT)" <53799235+ZihanChen-MSFT@users.noreply.github.com> Date: Tue, 8 Nov 2022 14:45:48 -0800 Subject: [PATCH 10/11] Fix code review comments --- .../typescript/components/componentsUtils.js | 49 +++++++++++-------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js b/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js index 5ac4978bb885..89c4ad64ac98 100644 --- a/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js +++ b/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js @@ -326,6 +326,33 @@ function getTypeAnnotationForArray( } } +function setDefaultValue( + common: $FlowFixMe, + defaultValue: $FlowFixMe | void +): void { + switch (common.type) { + case 'Int32TypeAnnotation': + case 'DoubleTypeAnnotation': + common.default = ((defaultValue ? defaultValue : 0): number); + break; + case 'FloatTypeAnnotation': + common.default = ((defaultValue === null + ? null + : defaultValue + ? defaultValue + : 0): number | null); + break; + case 'BooleanTypeAnnotation': + common.default = defaultValue === null ? null : !!defaultValue; + break; + case 'StringTypeAnnotation': + common.default = ((defaultValue === undefined ? null : defaultValue): + | string + | null); + break; + } +} + function getTypeAnnotation( name: string, annotation: $FlowFixMe | ASTNode, @@ -363,27 +390,7 @@ function getTypeAnnotation( buildSchema, ); if (common) { - switch (common.type) { - case 'Int32TypeAnnotation': - case 'DoubleTypeAnnotation': - common.default = ((defaultValue ? defaultValue : 0): number); - break; - case 'FloatTypeAnnotation': - common.default = ((defaultValue === null - ? null - : defaultValue - ? defaultValue - : 0): number | null); - break; - case 'BooleanTypeAnnotation': - common.default = defaultValue === null ? null : !!defaultValue; - break; - case 'StringTypeAnnotation': - common.default = ((defaultValue === undefined ? null : defaultValue): - | string - | null); - break; - } + setDefaultValue(common, defaultValue); return common; } From e897f9c9497614aff841ac17263bd17c116124b0 Mon Sep 17 00:00:00 2001 From: "Zihan Chen (MSFT)" <53799235+ZihanChen-MSFT@users.noreply.github.com> Date: Tue, 8 Nov 2022 14:47:09 -0800 Subject: [PATCH 11/11] yarn prettier --- .../src/parsers/typescript/components/componentsUtils.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js b/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js index 89c4ad64ac98..94f19b057355 100644 --- a/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js +++ b/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js @@ -197,7 +197,11 @@ function getCommonTypeAnnotation( case 'TSInterfaceDeclaration': return buildObjectType([typeAnnotation], types, buildSchema); case 'TSIntersectionType': - return buildObjectType(flattenIntersectionType(typeAnnotation, types), types, buildSchema); + return buildObjectType( + flattenIntersectionType(typeAnnotation, types), + types, + buildSchema, + ); case 'ImageSource': return { type: 'ReservedPropTypeAnnotation', @@ -328,7 +332,7 @@ function getTypeAnnotationForArray( function setDefaultValue( common: $FlowFixMe, - defaultValue: $FlowFixMe | void + defaultValue: $FlowFixMe | void, ): void { switch (common.type) { case 'Int32TypeAnnotation':