diff --git a/packages/react-native-codegen/BUCK b/packages/react-native-codegen/BUCK index 38e5f4c9c0d..857750a4926 100644 --- a/packages/react-native-codegen/BUCK +++ b/packages/react-native-codegen/BUCK @@ -71,6 +71,10 @@ rn_codegen_test( fixture_name = "IMAGE_PROP", ) +rn_codegen_test( + fixture_name = "ARRAY_PROPS", +) + rn_codegen_test( fixture_name = "MULTI_NATIVE_PROP", ) @@ -111,6 +115,7 @@ fb_xplat_cxx_binary( ], visibility = ["PUBLIC"], deps = [ + ":generated_components-ARRAY_PROPS", ":generated_components-BOOLEAN_PROP", ":generated_components-COLOR_PROP", ":generated_components-ENUM_PROP", @@ -146,6 +151,7 @@ rn_xplat_cxx_library( "PUBLIC", ], deps = [ + ":generated_components-ARRAY_PROPS", ":generated_components-BOOLEAN_PROP", ":generated_components-COLOR_PROP", ":generated_components-ENUM_PROP", diff --git a/packages/react-native-codegen/buck_tests/emptyFile.cpp b/packages/react-native-codegen/buck_tests/emptyFile.cpp index d08daa8d046..527f9d6910d 100644 --- a/packages/react-native-codegen/buck_tests/emptyFile.cpp +++ b/packages/react-native-codegen/buck_tests/emptyFile.cpp @@ -1,3 +1,4 @@ +#import #import #import #import diff --git a/packages/react-native-codegen/src/CodegenSchema.js b/packages/react-native-codegen/src/CodegenSchema.js index ee2d763f29e..d1b2b685b73 100644 --- a/packages/react-native-codegen/src/CodegenSchema.js +++ b/packages/react-native-codegen/src/CodegenSchema.js @@ -65,6 +65,10 @@ type PropTypeTypeAnnotation = | $ReadOnly<{| type: 'NativePrimitiveTypeAnnotation', name: 'ColorPrimitive' | 'ImageSourcePrimitive', + |}> + | $ReadOnly<{| + type: 'ArrayTypeAnnotation', + elementType: $ReadOnly, |}>; export type PropTypeShape = $ReadOnly<{| diff --git a/packages/react-native-codegen/src/generators/GeneratePropsCpp.js b/packages/react-native-codegen/src/generators/GeneratePropsCpp.js index 3a17aa0477b..b9ead297148 100644 --- a/packages/react-native-codegen/src/generators/GeneratePropsCpp.js +++ b/packages/react-native-codegen/src/generators/GeneratePropsCpp.js @@ -81,22 +81,32 @@ function getClassExtendString(component): string { function getImports(component): Set { const imports: Set = new Set(); + + function addImportsForNativeName(name) { + switch (name) { + case 'ColorPrimitive': + return; + case 'ImageSourcePrimitive': + imports.add('#include '); + return; + default: + (name: empty); + throw new Error(`Invalid name, got ${name}`); + } + } + component.props.forEach(prop => { const typeAnnotation = prop.typeAnnotation; if (typeAnnotation.type === 'NativePrimitiveTypeAnnotation') { - switch (typeAnnotation.name) { - case 'ColorPrimitive': - return; - case 'ImageSourcePrimitive': - imports.add('#include '); - return; - default: - (typeAnnotation.name: empty); - throw new Error( - `Invalid NativePrimitiveTypeAnnotation name, got ${prop.name}`, - ); - } + addImportsForNativeName(typeAnnotation.name); + } + + if ( + typeAnnotation.type === 'ArrayTypeAnnotation' && + typeAnnotation.elementType.type === 'NativePrimitiveTypeAnnotation' + ) { + addImportsForNativeName(typeAnnotation.elementType.name); } }); diff --git a/packages/react-native-codegen/src/generators/GeneratePropsH.js b/packages/react-native-codegen/src/generators/GeneratePropsH.js index 191efadb92e..bd47d4acf1e 100644 --- a/packages/react-native-codegen/src/generators/GeneratePropsH.js +++ b/packages/react-native-codegen/src/generators/GeneratePropsH.js @@ -113,6 +113,18 @@ function getNativeTypeFromAnnotation(componentName: string, prop): string { (typeAnnotation.name: empty); throw new Error('Receieved unknown NativePrimitiveTypeAnnotation'); } + case 'ArrayTypeAnnotation': { + if (typeAnnotation.elementType.type === 'ArrayTypeAnnotation') { + throw new Error( + 'ArrayTypeAnnotation of type ArrayTypeAnnotation not supported', + ); + } + const itemAnnotation = getNativeTypeFromAnnotation(componentName, { + typeAnnotation: typeAnnotation.elementType, + name: componentName, + }); + return `std::vector<${itemAnnotation}>`; + } case 'StringEnumTypeAnnotation': return getEnumName(componentName, prop.name); default: @@ -145,6 +157,9 @@ function convertDefaultTypeToString(componentName: string, prop): string { (typeAnnotation.name: empty); throw new Error('Receieved unknown NativePrimitiveTypeAnnotation'); } + case 'ArrayTypeAnnotation': { + return ''; + } case 'StringEnumTypeAnnotation': return `${getEnumName(componentName, prop.name)}::${upperCaseFirst( typeAnnotation.default, @@ -236,23 +251,38 @@ function getImports(component): Set { } }); + function addImportsForNativeName(name) { + switch (name) { + case 'ColorPrimitive': + imports.add('#include '); + return; + case 'ImageSourcePrimitive': + imports.add('#include '); + return; + default: + (name: empty); + throw new Error( + `Invalid NativePrimitiveTypeAnnotation name, got ${name}`, + ); + } + } + component.props.forEach(prop => { const typeAnnotation = prop.typeAnnotation; if (typeAnnotation.type === 'NativePrimitiveTypeAnnotation') { - switch (typeAnnotation.name) { - case 'ColorPrimitive': - imports.add('#include '); - return; - case 'ImageSourcePrimitive': - imports.add('#include '); - return; - default: - (typeAnnotation.name: empty); - throw new Error( - `Invalid NativePrimitiveTypeAnnotation name, got ${prop.name}`, - ); - } + addImportsForNativeName(typeAnnotation.name); + } + + if (typeAnnotation.type === 'ArrayTypeAnnotation') { + imports.add('#include '); + } + + if ( + typeAnnotation.type === 'ArrayTypeAnnotation' && + typeAnnotation.elementType.type === 'NativePrimitiveTypeAnnotation' + ) { + addImportsForNativeName(typeAnnotation.elementType.name); } }); diff --git a/packages/react-native-codegen/src/generators/GenerateViewConfigJs.js b/packages/react-native-codegen/src/generators/GenerateViewConfigJs.js index f19f54c18a9..f0d562e5098 100644 --- a/packages/react-native-codegen/src/generators/GenerateViewConfigJs.js +++ b/packages/react-native-codegen/src/generators/GenerateViewConfigJs.js @@ -43,6 +43,7 @@ function getReactDiffProcessValue(prop) { case 'StringTypeAnnotation': case 'Int32TypeAnnotation': case 'FloatTypeAnnotation': + case 'ArrayTypeAnnotation': case 'StringEnumTypeAnnotation': return j.literal(true); case 'NativePrimitiveTypeAnnotation': diff --git a/packages/react-native-codegen/src/generators/__test_fixtures__/fixtures.js b/packages/react-native-codegen/src/generators/__test_fixtures__/fixtures.js index bf3c0269ad8..2099bcc3dfe 100644 --- a/packages/react-native-codegen/src/generators/__test_fixtures__/fixtures.js +++ b/packages/react-native-codegen/src/generators/__test_fixtures__/fixtures.js @@ -284,6 +284,88 @@ const IMAGE_PROP: SchemaType = { }, }; +const ARRAY_PROPS: SchemaType = { + modules: { + Slider: { + components: { + ArrayPropsNativeComponent: { + extendsProps: [ + { + type: 'ReactNativeBuiltInType', + knownTypeName: 'ReactNativeCoreViewProps', + }, + ], + events: [], + props: [ + { + name: 'names', + optional: true, + typeAnnotation: { + type: 'ArrayTypeAnnotation', + elementType: { + type: 'StringTypeAnnotation', + }, + }, + }, + { + name: 'disableds', + optional: true, + typeAnnotation: { + type: 'ArrayTypeAnnotation', + elementType: { + type: 'BooleanTypeAnnotation', + }, + }, + }, + { + name: 'progress', + optional: true, + typeAnnotation: { + type: 'ArrayTypeAnnotation', + elementType: { + type: 'Int32TypeAnnotation', + }, + }, + }, + { + name: 'radii', + optional: true, + typeAnnotation: { + type: 'ArrayTypeAnnotation', + elementType: { + type: 'FloatTypeAnnotation', + }, + }, + }, + { + name: 'colors', + optional: true, + typeAnnotation: { + type: 'ArrayTypeAnnotation', + elementType: { + type: 'NativePrimitiveTypeAnnotation', + name: 'ColorPrimitive', + }, + }, + }, + { + name: 'srcs', + optional: true, + typeAnnotation: { + type: 'ArrayTypeAnnotation', + elementType: { + type: 'NativePrimitiveTypeAnnotation', + name: 'ImageSourcePrimitive', + }, + }, + }, + ], + }, + }, + }, + }, +}; + const MULTI_NATIVE_PROP: SchemaType = { modules: { Slider: { @@ -643,6 +725,7 @@ module.exports = { FLOAT_PROPS, COLOR_PROP, IMAGE_PROP, + ARRAY_PROPS, MULTI_NATIVE_PROP, ENUM_PROP, EVENT_PROPS, diff --git a/packages/react-native-codegen/src/generators/__tests__/GenerateComponentDescriptorH-test.js b/packages/react-native-codegen/src/generators/__tests__/GenerateComponentDescriptorH-test.js index f9c1d1d264c..780250782f5 100644 --- a/packages/react-native-codegen/src/generators/__tests__/GenerateComponentDescriptorH-test.js +++ b/packages/react-native-codegen/src/generators/__tests__/GenerateComponentDescriptorH-test.js @@ -14,6 +14,7 @@ const generator = require('../GenerateComponentDescriptorH.js'); const { + ARRAY_PROPS, BOOLEAN_PROP, STRING_PROP, INTEGER_PROPS, @@ -28,6 +29,10 @@ const { } = require('../__test_fixtures__/fixtures.js'); describe('GenerateComponentDescriptorH', () => { + it('can generate a array props', () => { + expect(generator.generate('ARRAY_PROPS', ARRAY_PROPS)).toMatchSnapshot(); + }); + it('can generate a single boolean prop', () => { expect(generator.generate('BOOLEAN_PROP', BOOLEAN_PROP)).toMatchSnapshot(); }); diff --git a/packages/react-native-codegen/src/generators/__tests__/__snapshots__/GenerateComponentDescriptorH-test.js.snap b/packages/react-native-codegen/src/generators/__tests__/__snapshots__/GenerateComponentDescriptorH-test.js.snap index 75dd517cf15..9a2e4a1bdde 100644 --- a/packages/react-native-codegen/src/generators/__tests__/__snapshots__/GenerateComponentDescriptorH-test.js.snap +++ b/packages/react-native-codegen/src/generators/__tests__/__snapshots__/GenerateComponentDescriptorH-test.js.snap @@ -1,5 +1,31 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`GenerateComponentDescriptorH can generate a array props 1`] = ` +Map { + "ComponentDescriptors.h" => " +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include + +namespace facebook { +namespace react { + +using ArrayPropsNativeComponentComponentDescriptor = ConcreteComponentDescriptor; + +} // namespace react +} // namespace facebook +", +} +`; + exports[`GenerateComponentDescriptorH can generate a native primitive image prop 1`] = ` Map { "ComponentDescriptors.h" => " diff --git a/packages/react-native-codegen/src/generators/__tests__/__snapshots__/GenerateEventEmitterCpp-test.js.snap b/packages/react-native-codegen/src/generators/__tests__/__snapshots__/GenerateEventEmitterCpp-test.js.snap index b55e9f5bac4..79bfc6fd052 100644 --- a/packages/react-native-codegen/src/generators/__tests__/__snapshots__/GenerateEventEmitterCpp-test.js.snap +++ b/packages/react-native-codegen/src/generators/__tests__/__snapshots__/GenerateEventEmitterCpp-test.js.snap @@ -1,5 +1,28 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`GenerateEventEmitterCpp can generate fixture ARRAY_PROPS 1`] = ` +Map { + "EventEmitters.cpp" => " +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include + +namespace facebook { +namespace react { + + + +} // namespace react +} // namespace facebook +", +} +`; + exports[`GenerateEventEmitterCpp can generate fixture BOOLEAN_PROP 1`] = ` Map { "EventEmitters.cpp" => " diff --git a/packages/react-native-codegen/src/generators/__tests__/__snapshots__/GenerateEventEmitterH-test.js.snap b/packages/react-native-codegen/src/generators/__tests__/__snapshots__/GenerateEventEmitterH-test.js.snap index 33bf6f768ff..99a6e0efca2 100644 --- a/packages/react-native-codegen/src/generators/__tests__/__snapshots__/GenerateEventEmitterH-test.js.snap +++ b/packages/react-native-codegen/src/generators/__tests__/__snapshots__/GenerateEventEmitterH-test.js.snap @@ -1,5 +1,29 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`GenerateEventEmitterH can generate fixture ARRAY_PROPS 1`] = ` +Map { + "EventEmitters.h" => " +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +#pragma once + +#include + +namespace facebook { +namespace react { + + + +} // namespace react +} // namespace facebook +", +} +`; + exports[`GenerateEventEmitterH can generate fixture BOOLEAN_PROP 1`] = ` Map { "EventEmitters.h" => " diff --git a/packages/react-native-codegen/src/generators/__tests__/__snapshots__/GeneratePropsCpp-test.js.snap b/packages/react-native-codegen/src/generators/__tests__/__snapshots__/GeneratePropsCpp-test.js.snap index e3e6ec4719c..88433dd182b 100644 --- a/packages/react-native-codegen/src/generators/__tests__/__snapshots__/GeneratePropsCpp-test.js.snap +++ b/packages/react-native-codegen/src/generators/__tests__/__snapshots__/GeneratePropsCpp-test.js.snap @@ -1,5 +1,40 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`GeneratePropsCpp can generate fixture ARRAY_PROPS 1`] = ` +Map { + "Props.cpp" => " +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include +#include +#include + +namespace facebook { +namespace react { + +ArrayPropsNativeComponentProps::ArrayPropsNativeComponentProps( + const ArrayPropsNativeComponentProps &sourceProps, + const RawProps &rawProps): ViewProps(sourceProps, rawProps), + + names(convertRawProp(rawProps, \\"names\\", sourceProps.names, names)), +disableds(convertRawProp(rawProps, \\"disableds\\", sourceProps.disableds, disableds)), +progress(convertRawProp(rawProps, \\"progress\\", sourceProps.progress, progress)), +radii(convertRawProp(rawProps, \\"radii\\", sourceProps.radii, radii)), +colors(convertRawProp(rawProps, \\"colors\\", sourceProps.colors, colors)), +srcs(convertRawProp(rawProps, \\"srcs\\", sourceProps.srcs, srcs)) + {} + +} // namespace react +} // namespace facebook +", +} +`; + exports[`GeneratePropsCpp can generate fixture BOOLEAN_PROP 1`] = ` Map { "Props.cpp" => " diff --git a/packages/react-native-codegen/src/generators/__tests__/__snapshots__/GeneratePropsH-test.js.snap b/packages/react-native-codegen/src/generators/__tests__/__snapshots__/GeneratePropsH-test.js.snap index 77d351181c3..46fb666b8a4 100644 --- a/packages/react-native-codegen/src/generators/__tests__/__snapshots__/GeneratePropsH-test.js.snap +++ b/packages/react-native-codegen/src/generators/__tests__/__snapshots__/GeneratePropsH-test.js.snap @@ -1,5 +1,45 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`GeneratePropsH can generate fixture ARRAY_PROPS 1`] = ` +Map { + "Props.h" => " +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +#pragma once + +#include +#include +#include +#include + +namespace facebook { +namespace react { + +class ArrayPropsNativeComponentProps final : public ViewProps { + public: + ArrayPropsNativeComponentProps() = default; + ArrayPropsNativeComponentProps(const ArrayPropsNativeComponentProps &sourceProps, const RawProps &rawProps); + +#pragma mark - Props + + const std::vector names{}; +const std::vector disableds{}; +const std::vector progress{}; +const std::vector radii{}; +const std::vector colors{}; +const std::vector srcs{}; +}; + +} // namespace react +} // namespace facebook +", +} +`; + exports[`GeneratePropsH can generate fixture BOOLEAN_PROP 1`] = ` Map { "Props.h" => " diff --git a/packages/react-native-codegen/src/generators/__tests__/__snapshots__/GenerateShadowNodeCpp-test.js.snap b/packages/react-native-codegen/src/generators/__tests__/__snapshots__/GenerateShadowNodeCpp-test.js.snap index 64a9a6f5f18..59f830b15b5 100644 --- a/packages/react-native-codegen/src/generators/__tests__/__snapshots__/GenerateShadowNodeCpp-test.js.snap +++ b/packages/react-native-codegen/src/generators/__tests__/__snapshots__/GenerateShadowNodeCpp-test.js.snap @@ -1,5 +1,28 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`GenerateShadowNodeCpp can generate fixture ARRAY_PROPS 1`] = ` +Map { + "ShadowNodes.cpp" => " +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include + +namespace facebook { +namespace react { + +extern const char ArrayPropsNativeComponentComponentName[] = \\"ArrayPropsNativeComponent\\"; + +} // namespace react +} // namespace facebook +", +} +`; + exports[`GenerateShadowNodeCpp can generate fixture BOOLEAN_PROP 1`] = ` Map { "ShadowNodes.cpp" => " diff --git a/packages/react-native-codegen/src/generators/__tests__/__snapshots__/GenerateShadowNodeH-test.js.snap b/packages/react-native-codegen/src/generators/__tests__/__snapshots__/GenerateShadowNodeH-test.js.snap index 9b40789cc62..364c007a330 100644 --- a/packages/react-native-codegen/src/generators/__tests__/__snapshots__/GenerateShadowNodeH-test.js.snap +++ b/packages/react-native-codegen/src/generators/__tests__/__snapshots__/GenerateShadowNodeH-test.js.snap @@ -1,5 +1,38 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`GenerateShadowNodeH can generate fixture ARRAY_PROPS 1`] = ` +Map { + "ShadowNodes.h" => " +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include + +namespace facebook { +namespace react { + +extern const char ArrayPropsNativeComponentComponentName[]; + +/* + * \`ShadowNode\` for component. + */ +using ArrayPropsNativeComponentShadowNode = ConcreteViewShadowNode< + ArrayPropsNativeComponentComponentName, + ArrayPropsNativeComponentProps>; + +} // namespace react +} // namespace facebook +", +} +`; + exports[`GenerateShadowNodeH can generate fixture BOOLEAN_PROP 1`] = ` Map { "ShadowNodes.h" => " diff --git a/packages/react-native-codegen/src/generators/__tests__/__snapshots__/GenerateViewConfigJs-test.js.snap b/packages/react-native-codegen/src/generators/__tests__/__snapshots__/GenerateViewConfigJs-test.js.snap index 16fca4bf0c1..6775c1bc7ba 100644 --- a/packages/react-native-codegen/src/generators/__tests__/__snapshots__/GenerateViewConfigJs-test.js.snap +++ b/packages/react-native-codegen/src/generators/__tests__/__snapshots__/GenerateViewConfigJs-test.js.snap @@ -1,5 +1,45 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`GenerateViewConfigJs can generate fixture ARRAY_PROPS 1`] = ` +Map { + "ViewConfigs.js" => " +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @format + * @flow + */ + +'use strict'; + +const ReactNativeStyleAttributes = require('ReactNativeStyleAttributes'); +const ReactNativeViewConfigRegistry = require('ReactNativeViewConfigRegistry'); + +const ArrayPropsNativeComponentViewConfig = { + uiViewClassName: 'ArrayPropsNativeComponent', + + validAttributes: { + names: true, + disableds: true, + progress: true, + radii: true, + colors: true, + srcs: true, + style: ReactNativeStyleAttributes + } +}; + +ReactNativeViewConfigRegistry.register( + 'ArrayPropsNativeComponent', + () => ArrayPropsNativeComponentViewConfig, +); +", +} +`; + exports[`GenerateViewConfigJs can generate fixture BOOLEAN_PROP 1`] = ` Map { "ViewConfigs.js" => "