From 9ae866c072aa75d68f60c150509e6916baf3edcc Mon Sep 17 00:00:00 2001 From: Eli White Date: Wed, 14 Aug 2019 16:07:10 -0700 Subject: [PATCH] Support spreading locally defined types deeply Summary: We want to be able to spread props at any level, not just the top level Reviewed By: JoshuaGross Differential Revision: D16812884 fbshipit-source-id: 2e710141f833a7cc7ea25a91a1523a5c43b4e02c --- .../components/__test_fixtures__/fixtures.js | 4 +++ .../component-parser-test.js.snap | 17 +++++++++++ .../src/parsers/flow/components/props.js | 29 ++++++++++++------- 3 files changed, 40 insertions(+), 10 deletions(-) diff --git a/packages/react-native-codegen/src/parsers/flow/components/__test_fixtures__/fixtures.js b/packages/react-native-codegen/src/parsers/flow/components/__test_fixtures__/fixtures.js index fc37d87c259..3d46afaec8f 100644 --- a/packages/react-native-codegen/src/parsers/flow/components/__test_fixtures__/fixtures.js +++ b/packages/react-native-codegen/src/parsers/flow/components/__test_fixtures__/fixtures.js @@ -450,6 +450,10 @@ export type ModuleProps = $ReadOnly<{| ...ViewProps, ...PropsInFile + + localType: $ReadOnly<{| + ...PropsInFile + |}> |}>; export default (codegenNativeComponent( diff --git a/packages/react-native-codegen/src/parsers/flow/components/__tests__/__snapshots__/component-parser-test.js.snap b/packages/react-native-codegen/src/parsers/flow/components/__tests__/__snapshots__/component-parser-test.js.snap index 6bdde34196f..5a1872ce4fe 100644 --- a/packages/react-native-codegen/src/parsers/flow/components/__tests__/__snapshots__/component-parser-test.js.snap +++ b/packages/react-native-codegen/src/parsers/flow/components/__tests__/__snapshots__/component-parser-test.js.snap @@ -4926,6 +4926,23 @@ Object { "type": "BooleanTypeAnnotation", }, }, + Object { + "name": "localType", + "optional": false, + "typeAnnotation": Object { + "properties": Array [ + Object { + "name": "isEnabled", + "optional": false, + "typeAnnotation": Object { + "default": false, + "type": "BooleanTypeAnnotation", + }, + }, + ], + "type": "ObjectTypeAnnotation", + }, + }, ], }, }, diff --git a/packages/react-native-codegen/src/parsers/flow/components/props.js b/packages/react-native-codegen/src/parsers/flow/components/props.js index 4b9857de657..e782e2ea268 100644 --- a/packages/react-native-codegen/src/parsers/flow/components/props.js +++ b/packages/react-native-codegen/src/parsers/flow/components/props.js @@ -123,9 +123,12 @@ function getTypeAnnotation(name, typeAnnotation, defaultValue, types) { ) { return { type: 'ObjectTypeAnnotation', - properties: typeAnnotation.typeParameters.params[0].properties.map(prop => - buildPropSchema(prop, types), - ), + properties: flattenProperties( + typeAnnotation.typeParameters.params[0].properties, + types, + ) + .map(prop => buildPropSchema(prop, types)) + .filter(Boolean), }; } @@ -299,19 +302,16 @@ function buildPropSchema(property, types: TypeMap): ?PropTypeShape { // $FlowFixMe there's no flowtype for ASTs type PropAST = Object; -function getProps( +function flattenProperties( typeDefinition: $ReadOnlyArray, types: TypeMap, -): $ReadOnlyArray { +) { return typeDefinition .map(property => { if (property.type === 'ObjectTypeProperty') { - return buildPropSchema(property, types); + return property; } else if (property.type === 'ObjectTypeSpreadProperty') { - return getProps( - getPropProperties(property.argument.id.name, types), - types[property.argument.id.name], - ); + return getPropProperties(property.argument.id.name, types); } }) .reduce((acc, item) => { @@ -325,6 +325,15 @@ function getProps( .filter(Boolean); } +function getProps( + typeDefinition: $ReadOnlyArray, + types: TypeMap, +): $ReadOnlyArray { + return flattenProperties(typeDefinition, types) + .map(property => buildPropSchema(property, types)) + .filter(Boolean); +} + module.exports = { getProps, getPropProperties,