From 91b9a27a7730b2bb11222694a88de05398caca95 Mon Sep 17 00:00:00 2001 From: Riccardo Cipolleschi Date: Wed, 21 Sep 2022 08:51:35 -0700 Subject: [PATCH] Parse custom NativeState in Flow (#34753) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/34753 This Diff introduce a the capability to parse custom NativeStates in Flow. To achieve this I also had to define the CodegenSchema. The parsing follows the exact same rules as props, as initial heuristic. This should allow enough customization for the developers who needs a custom state. There is only a case I was not able to make it work that is STATE_ALIASED_LOCALLY, from the fixtures. I don't know how diffuse it is and I think we can live with some workarounds for the time being. This diff also adds tests for the custom Native State Flow Parser. ## Changelog [General][Added] - Implement custom Native State parsing in Flow Differential Revision: D39686251 fbshipit-source-id: 77074d54546afffc8844aa8d8fcfdde5b0d8f589 --- .../react-native-codegen/src/CodegenSchema.js | 3 + .../__tests__/checkComponentSnaps-test.js | 13 +- .../components/__test_fixtures__/failures.js | 408 ++ .../components/__test_fixtures__/fixtures.js | 438 +- .../component-parser-test.js.snap | 3597 +++++++++++++---- .../src/parsers/flow/components/index.js | 39 +- .../src/parsers/flow/components/schema.js | 4 + .../src/parsers/flow/components/states.js | 493 +++ 8 files changed, 4160 insertions(+), 835 deletions(-) create mode 100644 packages/react-native-codegen/src/parsers/flow/components/states.js diff --git a/packages/react-native-codegen/src/CodegenSchema.js b/packages/react-native-codegen/src/CodegenSchema.js index 3e8857ec2be0a2..5f98933329e6fc 100644 --- a/packages/react-native-codegen/src/CodegenSchema.js +++ b/packages/react-native-codegen/src/CodegenSchema.js @@ -80,6 +80,7 @@ export type ComponentShape = $ReadOnly<{ events: $ReadOnlyArray, props: $ReadOnlyArray>, commands: $ReadOnlyArray>, + state?: $ReadOnlyArray>, }>; export type OptionsShape = $ReadOnly<{ @@ -185,6 +186,8 @@ export type ReservedPropTypeAnnotation = $ReadOnly<{ | 'EdgeInsetsPrimitive', }>; +export type StateTypeAnnotation = PropTypeAnnotation; + export type CommandTypeAnnotation = FunctionTypeAnnotation< CommandParamTypeAnnotation, VoidTypeAnnotation, 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 367bd9df5b3cd2..bb54ecb30c4aa6 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 @@ -14,10 +14,19 @@ const {compareSnaps, compareTsArraySnaps} = require('../compareSnaps.js'); const flowFixtures = require('../../flow/components/__test_fixtures__/fixtures.js'); const flowSnaps = require('../../../../src/parsers/flow/components/__tests__/__snapshots__/component-parser-test.js.snap'); -const flowExtraCases = []; +const flowExtraCases = [ + //TODO: remove these once we implement TypeScript parser for Custom State + 'ALL_STATE_TYPES', + 'ARRAY_STATE_TYPES', + 'COMMANDS_EVENTS_STATE_TYPES_EXPORTED', + 'OBJECT_STATE_TYPES', +]; const tsFixtures = require('../../typescript/components/__test_fixtures__/fixtures.js'); const tsSnaps = require('../../../../src/parsers/typescript/components/__tests__/__snapshots__/typescript-component-parser-test.js.snap'); -const tsExtraCases = ['ARRAY2_PROP_TYPES_NO_EVENTS']; +const tsExtraCases = ['ARRAY2_PROP_TYPES_NO_EVENTS'].concat([ + //TODO: remove these once we implement TypeScript parser for Custom State + 'COMMANDS_AND_EVENTS_TYPES_EXPORTED', +]); const ignoredCases = ['ARRAY_PROP_TYPES_NO_EVENTS']; compareSnaps( diff --git a/packages/react-native-codegen/src/parsers/flow/components/__test_fixtures__/failures.js b/packages/react-native-codegen/src/parsers/flow/components/__test_fixtures__/failures.js index 1d7072636a48a8..20d5b6044b6165 100644 --- a/packages/react-native-codegen/src/parsers/flow/components/__test_fixtures__/failures.js +++ b/packages/react-native-codegen/src/parsers/flow/components/__test_fixtures__/failures.js @@ -579,6 +579,402 @@ export default (codegenNativeComponent( ): HostComponent); `; +// === STATE === +const NULLABLE_STATE_WITH_DEFAULT = ` +/** + * 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. + * + * @format + * @flow strict-local + */ + +'use strict'; + +const codegenNativeComponent = require('codegenNativeComponent'); + +import type {WithDefault, Float} from 'CodegenTypes'; +import type {ViewProps} from 'ViewPropTypes'; +import type {HostComponent} from 'react-native'; + +export type ModuleProps = $ReadOnly<{| + ...ViewProps, + +|}>; + +export type ModuleNativeState = $ReadOnly<{| + nullable_with_default: ?WithDefault, +|}>; + +export default (codegenNativeComponent( + 'Module', +): HostComponent); +`; + +const NON_OPTIONAL_KEY_STATE_WITH_DEFAULT_VALUE = ` +/** + * 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. + * + * @format + * @flow strict-local + */ + +'use strict'; + +const codegenNativeComponent = require('codegenNativeComponent'); + +import type {WithDefault, Float} from 'CodegenTypes'; +import type {ViewProps} from 'ViewPropTypes'; +import type {HostComponent} from 'react-native'; + +export type ModuleProps = $ReadOnly<{| + ...ViewProps, + required_key_with_default: WithDefault, +|}>; + +export type ModuleNativeState = $ReadOnly<{| + required_key_with_default: WithDefault, +|}>; + +export default (codegenNativeComponent( + 'Module', +): HostComponent); +`; + +const STATE_CONFLICT_NAMES = ` +/** + * 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. + * + * @format + * @flow strict-local + */ + +'use strict'; + +import type {ViewProps} from 'ViewPropTypes'; +import type {HostComponent} from 'react-native'; + +const codegenNativeComponent = require('codegenNativeComponent'); + +export type ModuleProps = $ReadOnly<{| + ...ViewProps, + isEnabled: string, + + isEnabled: boolean, +|}>; + +export type ModuleNativeState = $ReadOnly<{| + isEnabled: string, + + isEnabled: boolean, +|}>; + +export default (codegenNativeComponent( + 'Module', +): HostComponent); +`; + +const STATE_CONFLICT_WITH_SPREAD_PROPS = ` +/** + * 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. + * + * @format + * @flow strict-local + */ + +'use strict'; + +import type {ViewProps} from 'ViewPropTypes'; +import type {HostComponent} from 'react-native'; + +const codegenNativeComponent = require('codegenNativeComponent'); + +type StateInFile = $ReadOnly<{| + isEnabled: boolean, +|}>; + +export type ModuleProps = $ReadOnly<{| + ...ViewProps, +|}>; + +export type ModuleNativeState = $ReadOnly<{| + ...StateInFile, + isEnabled: boolean, +|}>; + +export default (codegenNativeComponent( + 'Module', +): HostComponent); +`; + +const STATE_SPREAD_CONFLICTS_WITH_PROPS = ` +/** + * 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. + * + * @format + * @flow strict-local + */ + +'use strict'; + +import type {ViewProps} from 'ViewPropTypes'; +import type {HostComponent} from 'react-native'; + +const codegenNativeComponent = require('codegenNativeComponent'); + +type StateInFile = $ReadOnly<{| + isEnabled: boolean, +|}>; + +export type ModuleProps = $ReadOnly<{| + ...ViewProps, +|}>; + +export type ModuleNativeState = $ReadOnly<{| + isEnabled: boolean, + ...StateInFile, +|}>; + +export default (codegenNativeComponent( + 'Module', +): HostComponent); +`; + +const STATE_NUMBER_TYPE = ` +/** + * 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. + * + * @format + * @flow strict-local + */ + +'use strict'; + +import type {ViewProps} from 'ViewPropTypes'; +import type {HostComponent} from 'react-native'; + +const codegenNativeComponent = require('codegenNativeComponent'); + +export type ModuleProps = $ReadOnly<{| + ...ViewProps, +|}>; + +export type ModuleNativeState = $ReadOnly<{| + someProp: number +|}>; + +export default (codegenNativeComponent( + 'Module', +): HostComponent); +`; + +const STATE_MIXED_ENUM = ` +/** + * 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. + * + * @format + * @flow strict-local + */ + +'use strict'; + +import type {ViewProps} from 'ViewPropTypes'; +import type {HostComponent} from 'react-native'; + +const codegenNativeComponent = require('codegenNativeComponent'); + +export type ModuleProps = $ReadOnly<{| + ...ViewProps, +|}>; + +export type ModuleNativeState = $ReadOnly<{| + someProp?: WithDefault<'foo' | 1, 1> +|}>; + +export default (codegenNativeComponent( + 'Module', +): HostComponent); +`; + +const STATE_ENUM_BOOLEAN = ` +/** + * 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. + * + * @format + * @flow strict-local + */ + +'use strict'; + +import type {ViewProps} from 'ViewPropTypes'; +import type {HostComponent} from 'react-native'; + +const codegenNativeComponent = require('codegenNativeComponent'); + +export type ModuleProps = $ReadOnly<{| + ...ViewProps, +|}>; + +export type ModuleNativeState = $ReadOnly<{| + someProp?: WithDefault +|}>; + +export default (codegenNativeComponent( + 'Module', +): HostComponent); +`; + +const STATE_ARRAY_MIXED_ENUM = ` +/** + * 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. + * + * @format + * @flow strict-local + */ + +'use strict'; + +import type {ViewProps} from 'ViewPropTypes'; +import type {HostComponent} from 'react-native'; + +const codegenNativeComponent = require('codegenNativeComponent'); + +export type ModuleProps = $ReadOnly<{| + ...ViewProps, +|}>; + +export type ModuleNativeState = $ReadOnly<{| + someProp?: WithDefault<$ReadOnlyArray<'foo' | 1>, 1> +|}>; + +export default (codegenNativeComponent( + 'Module', +): HostComponent); +`; + +const STATE_ARRAY_ENUM_BOOLEAN = ` +/** + * 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. + * + * @format + * @flow strict-local + */ + +'use strict'; + +import type {ViewProps} from 'ViewPropTypes'; +import type {HostComponent} from 'react-native'; + +const codegenNativeComponent = require('codegenNativeComponent'); + +export type ModuleProps = $ReadOnly<{| + ...ViewProps, +|}>; + +export type ModuleNativeState = $ReadOnly<{| + someProp?: WithDefault<$ReadOnlyArray, false> +|}>; + +export default (codegenNativeComponent( + 'Module', +): HostComponent); +`; + +const STATE_ARRAY_ENUM_INT = ` +/** + * 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. + * + * @format + * @flow strict-local + */ + +'use strict'; + +import type {ViewProps} from 'ViewPropTypes'; +import type {HostComponent} from 'react-native'; + +const codegenNativeComponent = require('codegenNativeComponent'); + +export type ModuleProps = $ReadOnly<{| + ...ViewProps, +|}>; + +export type ModuleNativeState = $ReadOnly<{| + someProp?: WithDefault<$ReadOnlyArray<0 | 1>, 0> +|}>; + +export default (codegenNativeComponent( + 'Module', +): HostComponent); +`; + +const DOUBLE_STATE_IN_FILE = ` +/** + * 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. + * + * @format + * @flow strict-local + */ + +'use strict'; + +import type {ViewProps} from 'ViewPropTypes'; +import type {HostComponent} from 'react-native'; + +const codegenNativeComponent = require('codegenNativeComponent'); + +export type ModuleProps = $ReadOnly<{| + ...ViewProps, +|}>; + +type SecondNativeState = $ReadOnly<{| + someProp: boolean +|}>; + +export type FirstNativeState = $ReadOnly<{| + someOtherProp: boolean +|}>; + +export default (codegenNativeComponent( + 'Module', +): HostComponent); +`; + module.exports = { COMMANDS_DEFINED_INLINE, COMMANDS_DEFINED_MULTIPLE_TIMES, @@ -597,4 +993,16 @@ module.exports = { PROP_ARRAY_MIXED_ENUM, PROP_ARRAY_ENUM_BOOLEAN, PROP_ARRAY_ENUM_INT, + NULLABLE_STATE_WITH_DEFAULT, + NON_OPTIONAL_KEY_STATE_WITH_DEFAULT_VALUE, + STATE_CONFLICT_NAMES, + STATE_CONFLICT_WITH_SPREAD_PROPS, + STATE_SPREAD_CONFLICTS_WITH_PROPS, + STATE_NUMBER_TYPE, + STATE_MIXED_ENUM, + STATE_ENUM_BOOLEAN, + STATE_ARRAY_MIXED_ENUM, + STATE_ARRAY_ENUM_BOOLEAN, + STATE_ARRAY_ENUM_INT, + DOUBLE_STATE_IN_FILE, }; 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 6c94f1065b0c24..41ac2e97093c73 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 @@ -939,7 +939,7 @@ export default (codegenNativeComponent( ): NativeType); `; -const COMMANDS_AND_EVENTS_TYPES_EXPORTED = ` +const COMMANDS_EVENTS_STATE_TYPES_EXPORTED = ` /** * Copyright (c) Meta Platforms, Inc. and affiliates. * @@ -981,6 +981,13 @@ export type ModuleProps = $ReadOnly<{| onDirectEventDefinedInlineWithPaperName: DirectEventHandler, |}>; +// Add state here +export type ModuleNativeState = $ReadOnly<{| + boolean_required: boolean, + boolean_optional_key?: WithDefault, + boolean_optional_both?: WithDefault, +|}> + type NativeType = HostComponent; export type ScrollTo = (viewRef: React.ElementRef, y: Int, animated: Boolean) => Void; @@ -998,6 +1005,429 @@ export default (codegenNativeComponent( ): NativeType); `; +// === STATE === // +const ALL_STATE_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. + * + * @format + * @flow strict-local + */ + +'use strict'; + +const codegenNativeComponent = require('codegenNativeComponent'); + +import type {Int32, Double, Float, WithDefault} from 'CodegenTypes'; +import type {ImageSource} from 'ImageSource'; +import type {ColorValue, ColorArrayValue, PointValue, EdgeInsetsValue} from 'StyleSheetTypes'; +import type {ViewProps} from 'ViewPropTypes'; +import type {HostComponent} from 'react-native'; + +type ModuleProps = $ReadOnly<{| + ...ViewProps, +|}>; + +type ModuleNativeState = $ReadOnly<{| + // Boolean props + boolean_required: boolean, + boolean_optional_key?: WithDefault, + boolean_optional_both?: WithDefault, + + // Boolean props, null default + boolean_null_optional_key?: WithDefault, + boolean_null_optional_both?: WithDefault, + + // String props + string_required: string, + string_optional_key?: WithDefault, + string_optional_both?: WithDefault, + + // String props, null default + string_null_optional_key?: WithDefault, + string_null_optional_both?: WithDefault, + + // Stringish props + stringish_required: Stringish, + stringish_optional_key?: WithDefault, + stringish_optional_both?: WithDefault, + + // Stringish props, null default + stringish_null_optional_key?: WithDefault, + stringish_null_optional_both?: WithDefault, + + // Double props + double_required: Double, + double_optional_key?: WithDefault, + double_optional_both?: WithDefault, + + // Float props + float_required: Float, + float_optional_key?: WithDefault, + float_optional_both?: WithDefault, + + // Float props, null default + float_null_optional_key?: WithDefault, + float_null_optional_both?: WithDefault, + + // Int32 props + int32_required: Int32, + int32_optional_key?: WithDefault, + int32_optional_both?: WithDefault, + + // String enum props + enum_optional_key?: WithDefault<'small' | 'large', 'small'>, + enum_optional_both?: WithDefault<'small' | 'large', 'small'>, + + // Int enum props + int_enum_optional_key?: WithDefault<0 | 1, 0>, + + // Object props + object_optional_key?: $ReadOnly<{| prop: string |}>, + object_optional_both?: ?$ReadOnly<{| prop: string |}>, + object_optional_value: ?$ReadOnly<{| prop: string |}>, + + // ImageSource props + image_required: ImageSource, + image_optional_value: ?ImageSource, + image_optional_both?: ?ImageSource, + + // ColorValue props + color_required: ColorValue, + color_optional_key?: ColorValue, + color_optional_value: ?ColorValue, + color_optional_both?: ?ColorValue, + + // ColorArrayValue props + color_array_required: ColorArrayValue, + color_array_optional_key?: ColorArrayValue, + color_array_optional_value: ?ColorArrayValue, + color_array_optional_both?: ?ColorArrayValue, + + // ProcessedColorValue props + processed_color_required: ProcessedColorValue, + processed_color_optional_key?: ProcessedColorValue, + processed_color_optional_value: ?ProcessedColorValue, + processed_color_optional_both?: ?ProcessedColorValue, + + // PointValue props + point_required: PointValue, + point_optional_key?: PointValue, + point_optional_value: ?PointValue, + point_optional_both?: ?PointValue, + + // EdgeInsets props + insets_required: EdgeInsetsValue, + insets_optional_key?: EdgeInsetsValue, + insets_optional_value: ?EdgeInsetsValue, + insets_optional_both?: ?EdgeInsetsValue, +|}>; + +export default (codegenNativeComponent( + 'Module', +): HostComponent); +`; + +const ARRAY_STATE_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. + * + * @format + * @flow strict-local + */ + +'use strict'; + +const codegenNativeComponent = require('codegenNativeComponent'); + +import type {Int32, Double, Float, WithDefault} from 'CodegenTypes'; +import type {ImageSource} from 'ImageSource'; +import type {ColorValue, PointValue, ProcessColorValue, EdgeInsetsValue} from 'StyleSheetTypes'; +import type {ViewProps} from 'ViewPropTypes'; +import type {HostComponent} from 'react-native'; + +type ObjectType = $ReadOnly<{| prop: string |}>; +type ArrayObjectType = $ReadOnlyArray<$ReadOnly<{| prop: string |}>>; + +type ModuleProps = $ReadOnly<{| + ...ViewProps, +|}>; + +type ModuleNativeState = $ReadOnly<{| + // Props + // Boolean props + array_boolean_required: $ReadOnlyArray, + array_boolean_optional_key?: $ReadOnlyArray, + array_boolean_optional_value: ?$ReadOnlyArray, + array_boolean_optional_both?: ?$ReadOnlyArray, + + // String props + array_string_required: $ReadOnlyArray, + array_string_optional_key?: $ReadOnlyArray, + array_string_optional_value: ?$ReadOnlyArray, + array_string_optional_both?: ?$ReadOnlyArray, + + // Double props + array_double_required: $ReadOnlyArray, + array_double_optional_key?: $ReadOnlyArray, + array_double_optional_value: ?$ReadOnlyArray, + array_double_optional_both?: ?$ReadOnlyArray, + + // Float props + array_float_required: $ReadOnlyArray, + array_float_optional_key?: $ReadOnlyArray, + array_float_optional_value: ?$ReadOnlyArray, + array_float_optional_both?: ?$ReadOnlyArray, + + // Int32 props + array_int32_required: $ReadOnlyArray, + array_int32_optional_key?: $ReadOnlyArray, + array_int32_optional_value: ?$ReadOnlyArray, + array_int32_optional_both?: ?$ReadOnlyArray, + + // String enum props + array_enum_optional_key?: WithDefault< + $ReadOnlyArray<'small' | 'large'>, + 'small', + >, + array_enum_optional_both?: WithDefault< + $ReadOnlyArray<'small' | 'large'>, + 'small', + >, + + // ImageSource props + array_image_required: $ReadOnlyArray, + array_image_optional_key?: $ReadOnlyArray, + array_image_optional_value: ?$ReadOnlyArray, + array_image_optional_both?: ?$ReadOnlyArray, + + // ColorValue props + array_color_required: $ReadOnlyArray, + array_color_optional_key?: $ReadOnlyArray, + array_color_optional_value: ?$ReadOnlyArray, + array_color_optional_both?: ?$ReadOnlyArray, + + // PointValue props + array_point_required: $ReadOnlyArray, + array_point_optional_key?: $ReadOnlyArray, + array_point_optional_value: ?$ReadOnlyArray, + array_point_optional_both?: ?$ReadOnlyArray, + + // EdgeInsetsValue props + array_insets_required: $ReadOnlyArray, + array_insets_optional_key?: $ReadOnlyArray, + array_insets_optional_value: ?$ReadOnlyArray, + array_insets_optional_both?: ?$ReadOnlyArray, + + // Object props + array_object_required: $ReadOnlyArray<$ReadOnly<{| prop: string |}>>, + array_object_optional_key?: $ReadOnlyArray<$ReadOnly<{| prop: string |}>>, + array_object_optional_value: ?ArrayObjectType, + array_object_optional_both?: ?$ReadOnlyArray, + + // Nested array object types + array_of_array_object_required: $ReadOnlyArray< + $ReadOnly<{| + // This needs to be the same name as the top level array above + array_object_required: $ReadOnlyArray<$ReadOnly<{| prop: string |}>>, + |}> + >, + array_of_array_object_optional_key?: $ReadOnlyArray< + $ReadOnly<{| + // This needs to be the same name as the top level array above + array_object_optional_key: $ReadOnlyArray<$ReadOnly<{| prop?: string |}>>, + |}> + >, + array_of_array_object_optional_value: ?$ReadOnlyArray< + $ReadOnly<{| + // This needs to be the same name as the top level array above + array_object_optional_value: $ReadOnlyArray<$ReadOnly<{| prop: ?string |}>>, + |}> + >, + array_of_array_object_optional_both?: ?$ReadOnlyArray< + $ReadOnly<{| + // This needs to be the same name as the top level array above + array_object_optional_both: $ReadOnlyArray<$ReadOnly<{| prop?: ?string |}>>, + |}> + >, + + // Nested array of array of object types + array_of_array_of_object_required: $ReadOnlyArray< + $ReadOnlyArray< + $ReadOnly<{| + prop: string, + |}>, + >, + >, + + // Nested array of array of object types (in file) + 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<{| + ...ObjectType + |}>, + >, + >, +|}>; + +export default (codegenNativeComponent( + 'Module', +): HostComponent); +`; + +const OBJECT_STATE_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. + * + * @format + * @flow strict-local + */ + +'use strict'; + +const codegenNativeComponent = require('codegenNativeComponent'); + +import type {Int32, Double, Float, WithDefault} from 'CodegenTypes'; +import type {ImageSource} from 'ImageSource'; +import type {ColorValue, PointValue, EdgeInsetsValue} from 'StyleSheetTypes'; +import type {ViewProps} from 'ViewPropTypes'; +import type {HostComponent} from 'react-native'; + +type ModuleProps = $ReadOnly<{| + ...ViewProps, +|}>; + +type ModuleNativeState = $ReadOnly<{| + // Props + // Boolean props + boolean_required: $ReadOnly<{|prop: boolean|}>, + boolean_optional: $ReadOnly<{|prop?: WithDefault|}>, + + // String props + string_required: $ReadOnly<{|prop: string|}>, + string_optional: $ReadOnly<{|prop?: WithDefault|}>, + + // Double props + double_required: $ReadOnly<{|prop: Double|}>, + double_optional: $ReadOnly<{|prop?: WithDefault|}>, + + // Float props + float_required: $ReadOnly<{|prop: Float|}>, + float_optional: $ReadOnly<{|prop?: WithDefault|}>, + + // Int32 props + int_required: $ReadOnly<{|prop: Int32|}>, + int_optional: $ReadOnly<{|prop?: WithDefault|}>, + + // String enum props + enum_optional: $ReadOnly<{| + prop?: WithDefault<$ReadOnlyArray<'small' | 'large'>, 'small'>, + |}>, + + // ImageSource props + image_required: $ReadOnly<{|prop: ImageSource|}>, + image_optional_key: $ReadOnly<{|prop?: ImageSource|}>, + image_optional_value: $ReadOnly<{|prop: ?ImageSource|}>, + image_optional_both: $ReadOnly<{|prop?: ?ImageSource|}>, + + // ColorValue props + color_required: $ReadOnly<{|prop: ColorValue|}>, + color_optional_key: $ReadOnly<{|prop?: ColorValue|}>, + color_optional_value: $ReadOnly<{|prop: ?ColorValue|}>, + color_optional_both: $ReadOnly<{|prop?: ?ColorValue|}>, + + // ProcessedColorValue props + processed_color_required: $ReadOnly<{|prop: ProcessedColorValue|}>, + processed_color_optional_key: $ReadOnly<{|prop?: ProcessedColorValue|}>, + processed_color_optional_value: $ReadOnly<{|prop: ?ProcessedColorValue|}>, + processed_color_optional_both: $ReadOnly<{|prop?: ?ProcessedColorValue|}>, + + // PointValue props + point_required: $ReadOnly<{|prop: PointValue|}>, + point_optional_key: $ReadOnly<{|prop?: PointValue|}>, + point_optional_value: $ReadOnly<{|prop: ?PointValue|}>, + point_optional_both: $ReadOnly<{|prop?: ?PointValue|}>, + + // EdgeInsetsValue props + insets_required: $ReadOnly<{|prop: EdgeInsetsValue|}>, + insets_optional_key: $ReadOnly<{|prop?: EdgeInsetsValue|}>, + insets_optional_value: $ReadOnly<{|prop: ?EdgeInsetsValue|}>, + insets_optional_both: $ReadOnly<{|prop?: ?EdgeInsetsValue|}>, + + // Nested object props + object_required: $ReadOnly<{|prop: $ReadOnly<{nestedProp: string}>|}>, + object_optional_key?: $ReadOnly<{|prop: $ReadOnly<{nestedProp: string}>|}>, + object_optional_value: ?$ReadOnly<{|prop: $ReadOnly<{nestedProp: string}>|}>, + object_optional_both?: ?$ReadOnly<{|prop: $ReadOnly<{nestedProp: string}>|}>, +|}>; + +export default (codegenNativeComponent( + 'Module', +): HostComponent); +`; + +//TODO: fix this. The code is the same as per the props, but it fails with the State. +// const STATE_ALIASED_LOCALLY = ` +// /** +// * 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. +// * +// * @format +// * @flow strict-local +// */ + +// 'use strict'; + +// import type {ViewProps} from 'ViewPropTypes'; +// import type {HostComponent} from 'react-native'; + +// const codegenNativeComponent = require('codegenNativeComponent'); + +// type DeepSpread = $ReadOnly<{| +// otherStringProp: string, +// |}>; + +// export type StateInFile = $ReadOnly<{| +// ...DeepSpread, +// isEnabled: boolean, +// label: string, +// |}>; + +// export type ModuleProps = $ReadOnly<{| +// ...ViewProps, +// |}>; + +// export type ModuleNativeState = $ReadOnly<{| +// ...StateInFile, + +// localType: $ReadOnly<{| +// ...StateInFile +// |}>, + +// localArr: $ReadOnlyArray +// ||}>; + +// export default (codegenNativeComponent( +// 'Module', +// ): HostComponent); +// `; + module.exports = { ALL_PROP_TYPES_NO_EVENTS, ARRAY_PROP_TYPES_NO_EVENTS, @@ -1009,8 +1439,12 @@ module.exports = { EVENTS_DEFINED_INLINE_WITH_ALL_TYPES, EVENTS_DEFINED_AS_NULL_INLINE, PROPS_AND_EVENTS_TYPES_EXPORTED, - COMMANDS_AND_EVENTS_TYPES_EXPORTED, + COMMANDS_EVENTS_STATE_TYPES_EXPORTED, COMMANDS_DEFINED_WITH_ALL_TYPES, PROPS_AS_EXTERNAL_TYPES, COMMANDS_WITH_EXTERNAL_TYPES, + ALL_STATE_TYPES, + ARRAY_STATE_TYPES, + OBJECT_STATE_TYPES, + // STATE_ALIASED_LOCALLY, }; 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 5f52a06d543815..5dd86f7f66129a 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 @@ -12,8 +12,14 @@ exports[`RN Codegen Flow Parser Fails with error message COMMANDS_DEFINED_WITHOU exports[`RN Codegen Flow Parser Fails with error message COMMANDS_DEFINED_WITHOUT_REF 1`] = `"The first argument of method hotspotUpdate must be of type React.ElementRef<>"`; +exports[`RN Codegen Flow Parser Fails with error message DOUBLE_STATE_IN_FILE 1`] = `"Found 2 NativeStates for Module. Each component can have only 1 NativeState"`; + +exports[`RN Codegen Flow Parser Fails with error message NON_OPTIONAL_KEY_STATE_WITH_DEFAULT_VALUE 1`] = `"key required_key_with_default must be optional if used with WithDefault<> annotation"`; + exports[`RN Codegen Flow Parser Fails with error message NON_OPTIONAL_KEY_WITH_DEFAULT_VALUE 1`] = `"key required_key_with_default must be optional if used with WithDefault<> annotation"`; +exports[`RN Codegen Flow Parser Fails with error message NULLABLE_STATE_WITH_DEFAULT 1`] = `"WithDefault<> is optional and does not need to be marked as optional. Please remove the ? annotation in front of it."`; + exports[`RN Codegen Flow Parser Fails with error message NULLABLE_WITH_DEFAULT 1`] = `"WithDefault<> is optional and does not need to be marked as optional. Please remove the ? annotation in front of it."`; exports[`RN Codegen Flow Parser Fails with error message PROP_ARRAY_ENUM_BOOLEAN 1`] = `"Unsupported union type for \\"someProp\\", received \\"BooleanLiteralTypeAnnotation\\""`; @@ -34,6 +40,24 @@ exports[`RN Codegen Flow Parser Fails with error message PROPS_CONFLICT_WITH_SPR exports[`RN Codegen Flow Parser Fails with error message PROPS_SPREAD_CONFLICTS_WITH_PROPS 1`] = `"A prop was already defined with the name isEnabled"`; +exports[`RN Codegen Flow Parser Fails with error message STATE_ARRAY_ENUM_BOOLEAN 1`] = `"Unsupported union type for \\"someProp\\", received \\"BooleanLiteralTypeAnnotation\\""`; + +exports[`RN Codegen Flow Parser Fails with error message STATE_ARRAY_ENUM_INT 1`] = `"Arrays of int enums are not supported (see: \\"someProp\\")"`; + +exports[`RN Codegen Flow Parser Fails with error message STATE_ARRAY_MIXED_ENUM 1`] = `"Mixed types are not supported (see \\"someProp\\")."`; + +exports[`RN Codegen Flow Parser Fails with error message STATE_CONFLICT_NAMES 1`] = `"A prop was already defined with the name isEnabled"`; + +exports[`RN Codegen Flow Parser Fails with error message STATE_CONFLICT_WITH_SPREAD_PROPS 1`] = `"A property was already defined with the name isEnabled in the State"`; + +exports[`RN Codegen Flow Parser Fails with error message STATE_ENUM_BOOLEAN 1`] = `"Unsupported union type for \\"someProp\\", received \\"BooleanLiteralTypeAnnotation\\""`; + +exports[`RN Codegen Flow Parser Fails with error message STATE_MIXED_ENUM 1`] = `"Mixed types are not supported (see \\"someProp\\")."`; + +exports[`RN Codegen Flow Parser Fails with error message STATE_NUMBER_TYPE 1`] = `"Cannot use \\"NumberTypeAnnotation\\" type annotation for \\"someProp\\": must use a specific numeric type like Int32, Double, or Float"`; + +exports[`RN Codegen Flow Parser Fails with error message STATE_SPREAD_CONFLICTS_WITH_PROPS 1`] = `"A property was already defined with the name isEnabled in the State"`; + exports[`RN Codegen Flow Parser can generate fixture ALL_PROP_TYPES_NO_EVENTS 1`] = ` "{ 'modules': { @@ -549,7 +573,7 @@ exports[`RN Codegen Flow Parser can generate fixture ALL_PROP_TYPES_NO_EVENTS 1` }" `; -exports[`RN Codegen Flow Parser can generate fixture ARRAY_PROP_TYPES_NO_EVENTS 1`] = ` +exports[`RN Codegen Flow Parser can generate fixture ALL_STATE_TYPES 1`] = ` "{ 'modules': { 'Module': { @@ -563,692 +587,501 @@ exports[`RN Codegen Flow Parser can generate fixture ARRAY_PROP_TYPES_NO_EVENTS } ], 'events': [], - 'props': [ + 'props': [], + 'commands': [], + 'state': [ { - 'name': 'array_boolean_required', + 'name': 'boolean_required', 'optional': false, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'BooleanTypeAnnotation' - } + 'type': 'BooleanTypeAnnotation', + 'default': false } }, { - 'name': 'array_boolean_optional_key', + 'name': 'boolean_optional_key', 'optional': true, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'BooleanTypeAnnotation' - } + 'type': 'BooleanTypeAnnotation', + 'default': true } }, { - 'name': 'array_boolean_optional_value', + 'name': 'boolean_optional_both', 'optional': true, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'BooleanTypeAnnotation' - } + 'type': 'BooleanTypeAnnotation', + 'default': true } }, { - 'name': 'array_boolean_optional_both', + 'name': 'boolean_null_optional_key', 'optional': true, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'BooleanTypeAnnotation' - } + 'type': 'BooleanTypeAnnotation', + 'default': null } }, { - 'name': 'array_string_required', + 'name': 'boolean_null_optional_both', + 'optional': true, + 'typeAnnotation': { + 'type': 'BooleanTypeAnnotation', + 'default': null + } + }, + { + 'name': 'string_required', 'optional': false, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'StringTypeAnnotation' - } + 'type': 'StringTypeAnnotation', + 'default': null } }, { - 'name': 'array_string_optional_key', + 'name': 'string_optional_key', 'optional': true, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'StringTypeAnnotation' - } + 'type': 'StringTypeAnnotation', + 'default': '' } }, { - 'name': 'array_string_optional_value', + 'name': 'string_optional_both', 'optional': true, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'StringTypeAnnotation' - } + 'type': 'StringTypeAnnotation', + 'default': '' } }, { - 'name': 'array_string_optional_both', + 'name': 'string_null_optional_key', 'optional': true, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'StringTypeAnnotation' - } + 'type': 'StringTypeAnnotation', + 'default': null } }, { - 'name': 'array_double_required', - 'optional': false, + 'name': 'string_null_optional_both', + 'optional': true, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'DoubleTypeAnnotation' - } + 'type': 'StringTypeAnnotation', + 'default': null } }, { - 'name': 'array_double_optional_key', - 'optional': true, + 'name': 'stringish_required', + 'optional': false, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'DoubleTypeAnnotation' - } + 'type': 'StringTypeAnnotation', + 'default': null } }, { - 'name': 'array_double_optional_value', + 'name': 'stringish_optional_key', 'optional': true, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'DoubleTypeAnnotation' - } + 'type': 'StringTypeAnnotation', + 'default': '' } }, { - 'name': 'array_double_optional_both', + 'name': 'stringish_optional_both', 'optional': true, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'DoubleTypeAnnotation' - } + 'type': 'StringTypeAnnotation', + 'default': '' } }, { - 'name': 'array_float_required', - 'optional': false, + 'name': 'stringish_null_optional_key', + 'optional': true, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'FloatTypeAnnotation' - } + 'type': 'StringTypeAnnotation', + 'default': null } }, { - 'name': 'array_float_optional_key', + 'name': 'stringish_null_optional_both', 'optional': true, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'FloatTypeAnnotation' - } + 'type': 'StringTypeAnnotation', + 'default': null } }, { - 'name': 'array_float_optional_value', - 'optional': true, + 'name': 'double_required', + 'optional': false, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'FloatTypeAnnotation' - } + 'type': 'DoubleTypeAnnotation', + 'default': 0 } }, { - 'name': 'array_float_optional_both', + 'name': 'double_optional_key', 'optional': true, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'FloatTypeAnnotation' - } + 'type': 'DoubleTypeAnnotation', + 'default': 1.1 } }, { - 'name': 'array_int32_required', - 'optional': false, + 'name': 'double_optional_both', + 'optional': true, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'Int32TypeAnnotation' - } + 'type': 'DoubleTypeAnnotation', + 'default': 1.1 } }, { - 'name': 'array_int32_optional_key', - 'optional': true, + 'name': 'float_required', + 'optional': false, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'Int32TypeAnnotation' - } + 'type': 'FloatTypeAnnotation', + 'default': 0 } }, { - 'name': 'array_int32_optional_value', + 'name': 'float_optional_key', 'optional': true, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'Int32TypeAnnotation' - } + 'type': 'FloatTypeAnnotation', + 'default': 1.1 } }, { - 'name': 'array_int32_optional_both', + 'name': 'float_optional_both', 'optional': true, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'Int32TypeAnnotation' - } + 'type': 'FloatTypeAnnotation', + 'default': 1.1 } }, { - 'name': 'array_enum_optional_key', + 'name': 'float_null_optional_key', 'optional': true, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'StringEnumTypeAnnotation', - 'default': 'small', - 'options': [ - 'small', - 'large' - ] - } + 'type': 'FloatTypeAnnotation', + 'default': null } }, { - 'name': 'array_enum_optional_both', + 'name': 'float_null_optional_both', 'optional': true, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'StringEnumTypeAnnotation', - 'default': 'small', - 'options': [ - 'small', - 'large' - ] - } + 'type': 'FloatTypeAnnotation', + 'default': null } }, { - 'name': 'array_image_required', + 'name': 'int32_required', 'optional': false, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'ReservedPropTypeAnnotation', - 'name': 'ImageSourcePrimitive' - } + 'type': 'Int32TypeAnnotation', + 'default': 0 } }, { - 'name': 'array_image_optional_key', + 'name': 'int32_optional_key', 'optional': true, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'ReservedPropTypeAnnotation', - 'name': 'ImageSourcePrimitive' - } + 'type': 'Int32TypeAnnotation', + 'default': 1 } }, { - 'name': 'array_image_optional_value', + 'name': 'int32_optional_both', 'optional': true, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'ReservedPropTypeAnnotation', - 'name': 'ImageSourcePrimitive' - } + 'type': 'Int32TypeAnnotation', + 'default': 1 } }, { - 'name': 'array_image_optional_both', + 'name': 'enum_optional_key', 'optional': true, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'ReservedPropTypeAnnotation', - 'name': 'ImageSourcePrimitive' - } - } + 'type': 'StringEnumTypeAnnotation', + 'default': 'small', + 'options': [ + 'small', + 'large' + ] + } }, { - 'name': 'array_color_required', - 'optional': false, + 'name': 'enum_optional_both', + 'optional': true, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'ReservedPropTypeAnnotation', - 'name': 'ColorPrimitive' - } + 'type': 'StringEnumTypeAnnotation', + 'default': 'small', + 'options': [ + 'small', + 'large' + ] } }, { - 'name': 'array_color_optional_key', + 'name': 'int_enum_optional_key', 'optional': true, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'ReservedPropTypeAnnotation', - 'name': 'ColorPrimitive' - } + 'type': 'Int32EnumTypeAnnotation', + 'default': 0, + 'options': [ + 0, + 1 + ] } }, { - 'name': 'array_color_optional_value', + 'name': 'object_optional_key', 'optional': true, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'ReservedPropTypeAnnotation', - 'name': 'ColorPrimitive' - } + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': false, + 'typeAnnotation': { + 'type': 'StringTypeAnnotation', + 'default': null + } + } + ] } }, { - 'name': 'array_color_optional_both', + 'name': 'object_optional_both', 'optional': true, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'ReservedPropTypeAnnotation', - 'name': 'ColorPrimitive' - } + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': false, + 'typeAnnotation': { + 'type': 'StringTypeAnnotation', + 'default': null + } + } + ] } }, { - 'name': 'array_point_required', + 'name': 'object_optional_value', + 'optional': true, + 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': false, + 'typeAnnotation': { + 'type': 'StringTypeAnnotation', + 'default': null + } + } + ] + } + }, + { + 'name': 'image_required', 'optional': false, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'ReservedPropTypeAnnotation', - 'name': 'PointPrimitive' - } + 'type': 'ReservedPropTypeAnnotation', + 'name': 'ImageSourcePrimitive' } }, { - 'name': 'array_point_optional_key', + 'name': 'image_optional_value', 'optional': true, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'ReservedPropTypeAnnotation', - 'name': 'PointPrimitive' - } + 'type': 'ReservedPropTypeAnnotation', + 'name': 'ImageSourcePrimitive' } }, { - 'name': 'array_point_optional_value', + 'name': 'image_optional_both', 'optional': true, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'ReservedPropTypeAnnotation', - 'name': 'PointPrimitive' - } + 'type': 'ReservedPropTypeAnnotation', + 'name': 'ImageSourcePrimitive' } }, { - 'name': 'array_point_optional_both', + 'name': 'color_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'ColorPrimitive' + } + }, + { + 'name': 'color_optional_key', 'optional': true, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'ReservedPropTypeAnnotation', - 'name': 'PointPrimitive' - } + 'type': 'ReservedPropTypeAnnotation', + 'name': 'ColorPrimitive' } }, { - 'name': 'array_insets_required', + 'name': 'color_optional_value', + 'optional': true, + 'typeAnnotation': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'ColorPrimitive' + } + }, + { + 'name': 'color_optional_both', + 'optional': true, + 'typeAnnotation': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'ColorPrimitive' + } + }, + { + 'name': 'color_array_required', 'optional': false, 'typeAnnotation': { 'type': 'ArrayTypeAnnotation', 'elementType': { 'type': 'ReservedPropTypeAnnotation', - 'name': 'EdgeInsetsPrimitive' + 'name': 'ColorPrimitive' } } }, { - 'name': 'array_insets_optional_key', + 'name': 'color_array_optional_key', 'optional': true, 'typeAnnotation': { 'type': 'ArrayTypeAnnotation', 'elementType': { 'type': 'ReservedPropTypeAnnotation', - 'name': 'EdgeInsetsPrimitive' + 'name': 'ColorPrimitive' } } }, { - 'name': 'array_insets_optional_value', + 'name': 'color_array_optional_value', 'optional': true, 'typeAnnotation': { 'type': 'ArrayTypeAnnotation', 'elementType': { 'type': 'ReservedPropTypeAnnotation', - 'name': 'EdgeInsetsPrimitive' + 'name': 'ColorPrimitive' } } }, { - 'name': 'array_insets_optional_both', + 'name': 'color_array_optional_both', 'optional': true, 'typeAnnotation': { 'type': 'ArrayTypeAnnotation', 'elementType': { 'type': 'ReservedPropTypeAnnotation', - 'name': 'EdgeInsetsPrimitive' + 'name': 'ColorPrimitive' } } }, { - 'name': 'array_object_required', + 'name': 'processed_color_required', 'optional': false, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'ObjectTypeAnnotation', - 'properties': [ - { - 'name': 'prop', - 'optional': false, - 'typeAnnotation': { - 'type': 'StringTypeAnnotation', - 'default': null - } - } - ] - } + 'type': 'ReservedPropTypeAnnotation', + 'name': 'ColorPrimitive' } }, { - 'name': 'array_object_optional_key', + 'name': 'processed_color_optional_key', 'optional': true, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'ObjectTypeAnnotation', - 'properties': [ - { - 'name': 'prop', - 'optional': false, - 'typeAnnotation': { - 'type': 'StringTypeAnnotation', - 'default': null - } - } - ] - } + 'type': 'ReservedPropTypeAnnotation', + 'name': 'ColorPrimitive' } }, { - 'name': 'array_object_optional_value', + 'name': 'processed_color_optional_value', 'optional': true, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'ObjectTypeAnnotation', - 'properties': [ - { - 'name': 'prop', - 'optional': false, - 'typeAnnotation': { - 'type': 'StringTypeAnnotation', - 'default': null - } - } - ] - } + 'type': 'ReservedPropTypeAnnotation', + 'name': 'ColorPrimitive' } }, { - 'name': 'array_object_optional_both', + 'name': 'processed_color_optional_both', 'optional': true, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'ObjectTypeAnnotation', - 'properties': [ - { - 'name': 'prop', - 'optional': false, - 'typeAnnotation': { - 'type': 'StringTypeAnnotation', - 'default': null - } - } - ] - } + 'type': 'ReservedPropTypeAnnotation', + 'name': 'ColorPrimitive' } }, { - 'name': 'array_of_array_object_required', + 'name': 'point_required', 'optional': false, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'ObjectTypeAnnotation', - 'properties': [ - { - 'name': 'array_object_required', - 'optional': false, - 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'ObjectTypeAnnotation', - 'properties': [ - { - 'name': 'prop', - 'optional': false, - 'typeAnnotation': { - 'type': 'StringTypeAnnotation', - 'default': null - } - } - ] - } - } - } - ] - } + 'type': 'ReservedPropTypeAnnotation', + 'name': 'PointPrimitive' } }, { - 'name': 'array_of_array_object_optional_key', + 'name': 'point_optional_key', 'optional': true, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'ObjectTypeAnnotation', - 'properties': [ - { - 'name': 'array_object_optional_key', - 'optional': false, - 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'ObjectTypeAnnotation', - 'properties': [ - { - 'name': 'prop', - 'optional': true, - 'typeAnnotation': { - 'type': 'StringTypeAnnotation', - 'default': null - } - } - ] - } - } - } - ] - } + 'type': 'ReservedPropTypeAnnotation', + 'name': 'PointPrimitive' } }, { - 'name': 'array_of_array_object_optional_value', + 'name': 'point_optional_value', 'optional': true, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'ObjectTypeAnnotation', - 'properties': [ - { - 'name': 'array_object_optional_value', - 'optional': false, - 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'ObjectTypeAnnotation', - 'properties': [ - { - 'name': 'prop', - 'optional': true, - 'typeAnnotation': { - 'type': 'StringTypeAnnotation', - 'default': null - } - } - ] - } - } - } - ] - } + 'type': 'ReservedPropTypeAnnotation', + 'name': 'PointPrimitive' } }, { - 'name': 'array_of_array_object_optional_both', + 'name': 'point_optional_both', 'optional': true, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'ObjectTypeAnnotation', - 'properties': [ - { - 'name': 'array_object_optional_both', - 'optional': false, - 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'ObjectTypeAnnotation', - 'properties': [ - { - 'name': 'prop', - 'optional': true, - 'typeAnnotation': { - 'type': 'StringTypeAnnotation', - 'default': null - } - } - ] - } - } - } - ] - } + 'type': 'ReservedPropTypeAnnotation', + 'name': 'PointPrimitive' } }, { - 'name': 'array_of_array_of_object_required', + 'name': 'insets_required', 'optional': false, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'ObjectTypeAnnotation', - 'properties': [ - { - 'name': 'prop', - 'optional': false, - 'typeAnnotation': { - 'type': 'StringTypeAnnotation', - 'default': null - } - } - ] - } - } + 'type': 'ReservedPropTypeAnnotation', + 'name': 'EdgeInsetsPrimitive' } }, { - 'name': 'array_of_array_of_object_required_in_file', - 'optional': false, + 'name': 'insets_optional_key', + 'optional': true, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'ObjectTypeAnnotation', - 'properties': [ - { - 'name': 'prop', - 'optional': false, - 'typeAnnotation': { - 'type': 'StringTypeAnnotation', - 'default': null - } - } - ] - } - } + 'type': 'ReservedPropTypeAnnotation', + 'name': 'EdgeInsetsPrimitive' } }, { - 'name': 'array_of_array_of_object_required_with_spread', - 'optional': false, + 'name': 'insets_optional_value', + 'optional': true, 'typeAnnotation': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'ArrayTypeAnnotation', - 'elementType': { - 'type': 'ObjectTypeAnnotation', - 'properties': [ - { - 'name': 'prop', - 'optional': false, - 'typeAnnotation': { - 'type': 'StringTypeAnnotation', - 'default': null - } - } - ] - } - } + 'type': 'ReservedPropTypeAnnotation', + 'name': 'EdgeInsetsPrimitive' + } + }, + { + 'name': 'insets_optional_both', + 'optional': true, + 'typeAnnotation': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'EdgeInsetsPrimitive' } } - ], - 'commands': [] + ] } } } @@ -1256,7 +1089,7 @@ exports[`RN Codegen Flow Parser can generate fixture ARRAY_PROP_TYPES_NO_EVENTS }" `; -exports[`RN Codegen Flow Parser can generate fixture COMMANDS_AND_EVENTS_TYPES_EXPORTED 1`] = ` +exports[`RN Codegen Flow Parser can generate fixture ARRAY_PROP_TYPES_NO_EVENTS 1`] = ` "{ 'modules': { 'Module': { @@ -1269,83 +1102,1601 @@ exports[`RN Codegen Flow Parser can generate fixture COMMANDS_AND_EVENTS_TYPES_E 'knownTypeName': 'ReactNativeCoreViewProps' } ], - 'events': [ + 'events': [], + 'props': [ { - 'name': 'onBubblingEventDefinedInline', + 'name': 'array_boolean_required', 'optional': false, - 'bubblingType': 'bubble', 'typeAnnotation': { - 'type': 'EventTypeAnnotation', - 'argument': { - 'type': 'ObjectTypeAnnotation', - 'properties': [ - { - 'name': 'boolean_required', - 'optional': false, - 'typeAnnotation': { - 'type': 'BooleanTypeAnnotation' - } - }, - { - 'name': 'boolean_optional_key', - 'optional': true, - 'typeAnnotation': { - 'type': 'BooleanTypeAnnotation' - } - }, - { - 'name': 'boolean_optional_value', - 'optional': true, - 'typeAnnotation': { - 'type': 'BooleanTypeAnnotation' - } - }, - { - 'name': 'boolean_optional_both', - 'optional': true, - 'typeAnnotation': { - 'type': 'BooleanTypeAnnotation' - } - }, - { - 'name': 'string_required', - 'optional': false, - 'typeAnnotation': { - 'type': 'StringTypeAnnotation' - } - }, - { - 'name': 'string_optional_key', - 'optional': true, - 'typeAnnotation': { - 'type': 'StringTypeAnnotation' - } - }, - { - 'name': 'string_optional_value', - 'optional': true, - 'typeAnnotation': { - 'type': 'StringTypeAnnotation' - } - }, - { - 'name': 'string_optional_both', - 'optional': true, - 'typeAnnotation': { - 'type': 'StringTypeAnnotation' - } - }, - { - 'name': 'double_required', - 'optional': false, - 'typeAnnotation': { - 'type': 'DoubleTypeAnnotation' - } - }, - { - 'name': 'double_optional_key', - 'optional': true, - 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'BooleanTypeAnnotation' + } + } + }, + { + 'name': 'array_boolean_optional_key', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'BooleanTypeAnnotation' + } + } + }, + { + 'name': 'array_boolean_optional_value', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'BooleanTypeAnnotation' + } + } + }, + { + 'name': 'array_boolean_optional_both', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'BooleanTypeAnnotation' + } + } + }, + { + 'name': 'array_string_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'StringTypeAnnotation' + } + } + }, + { + 'name': 'array_string_optional_key', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'StringTypeAnnotation' + } + } + }, + { + 'name': 'array_string_optional_value', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'StringTypeAnnotation' + } + } + }, + { + 'name': 'array_string_optional_both', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'StringTypeAnnotation' + } + } + }, + { + 'name': 'array_double_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'DoubleTypeAnnotation' + } + } + }, + { + 'name': 'array_double_optional_key', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'DoubleTypeAnnotation' + } + } + }, + { + 'name': 'array_double_optional_value', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'DoubleTypeAnnotation' + } + } + }, + { + 'name': 'array_double_optional_both', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'DoubleTypeAnnotation' + } + } + }, + { + 'name': 'array_float_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'FloatTypeAnnotation' + } + } + }, + { + 'name': 'array_float_optional_key', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'FloatTypeAnnotation' + } + } + }, + { + 'name': 'array_float_optional_value', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'FloatTypeAnnotation' + } + } + }, + { + 'name': 'array_float_optional_both', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'FloatTypeAnnotation' + } + } + }, + { + 'name': 'array_int32_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'Int32TypeAnnotation' + } + } + }, + { + 'name': 'array_int32_optional_key', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'Int32TypeAnnotation' + } + } + }, + { + 'name': 'array_int32_optional_value', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'Int32TypeAnnotation' + } + } + }, + { + 'name': 'array_int32_optional_both', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'Int32TypeAnnotation' + } + } + }, + { + 'name': 'array_enum_optional_key', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'StringEnumTypeAnnotation', + 'default': 'small', + 'options': [ + 'small', + 'large' + ] + } + } + }, + { + 'name': 'array_enum_optional_both', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'StringEnumTypeAnnotation', + 'default': 'small', + 'options': [ + 'small', + 'large' + ] + } + } + }, + { + 'name': 'array_image_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'ImageSourcePrimitive' + } + } + }, + { + 'name': 'array_image_optional_key', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'ImageSourcePrimitive' + } + } + }, + { + 'name': 'array_image_optional_value', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'ImageSourcePrimitive' + } + } + }, + { + 'name': 'array_image_optional_both', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'ImageSourcePrimitive' + } + } + }, + { + 'name': 'array_color_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'ColorPrimitive' + } + } + }, + { + 'name': 'array_color_optional_key', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'ColorPrimitive' + } + } + }, + { + 'name': 'array_color_optional_value', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'ColorPrimitive' + } + } + }, + { + 'name': 'array_color_optional_both', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'ColorPrimitive' + } + } + }, + { + 'name': 'array_point_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'PointPrimitive' + } + } + }, + { + 'name': 'array_point_optional_key', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'PointPrimitive' + } + } + }, + { + 'name': 'array_point_optional_value', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'PointPrimitive' + } + } + }, + { + 'name': 'array_point_optional_both', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'PointPrimitive' + } + } + }, + { + 'name': 'array_insets_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'EdgeInsetsPrimitive' + } + } + }, + { + 'name': 'array_insets_optional_key', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'EdgeInsetsPrimitive' + } + } + }, + { + 'name': 'array_insets_optional_value', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'EdgeInsetsPrimitive' + } + } + }, + { + 'name': 'array_insets_optional_both', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'EdgeInsetsPrimitive' + } + } + }, + { + 'name': 'array_object_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': false, + 'typeAnnotation': { + 'type': 'StringTypeAnnotation', + 'default': null + } + } + ] + } + } + }, + { + 'name': 'array_object_optional_key', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': false, + 'typeAnnotation': { + 'type': 'StringTypeAnnotation', + 'default': null + } + } + ] + } + } + }, + { + 'name': 'array_object_optional_value', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': false, + 'typeAnnotation': { + 'type': 'StringTypeAnnotation', + 'default': null + } + } + ] + } + } + }, + { + 'name': 'array_object_optional_both', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': false, + 'typeAnnotation': { + 'type': 'StringTypeAnnotation', + 'default': null + } + } + ] + } + } + }, + { + 'name': 'array_of_array_object_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'array_object_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': false, + 'typeAnnotation': { + 'type': 'StringTypeAnnotation', + 'default': null + } + } + ] + } + } + } + ] + } + } + }, + { + 'name': 'array_of_array_object_optional_key', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'array_object_optional_key', + 'optional': false, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': true, + 'typeAnnotation': { + 'type': 'StringTypeAnnotation', + 'default': null + } + } + ] + } + } + } + ] + } + } + }, + { + 'name': 'array_of_array_object_optional_value', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'array_object_optional_value', + 'optional': false, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': true, + 'typeAnnotation': { + 'type': 'StringTypeAnnotation', + 'default': null + } + } + ] + } + } + } + ] + } + } + }, + { + 'name': 'array_of_array_object_optional_both', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'array_object_optional_both', + 'optional': false, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': true, + 'typeAnnotation': { + 'type': 'StringTypeAnnotation', + 'default': null + } + } + ] + } + } + } + ] + } + } + }, + { + 'name': 'array_of_array_of_object_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': false, + 'typeAnnotation': { + 'type': 'StringTypeAnnotation', + 'default': null + } + } + ] + } + } + } + }, + { + 'name': 'array_of_array_of_object_required_in_file', + 'optional': false, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': false, + 'typeAnnotation': { + 'type': 'StringTypeAnnotation', + 'default': null + } + } + ] + } + } + } + }, + { + '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': [] + } + } + } + } +}" +`; + +exports[`RN Codegen Flow Parser can generate fixture ARRAY_STATE_TYPES 1`] = ` +"{ + 'modules': { + 'Module': { + 'type': 'Component', + 'components': { + 'Module': { + 'extendsProps': [ + { + 'type': 'ReactNativeBuiltInType', + 'knownTypeName': 'ReactNativeCoreViewProps' + } + ], + 'events': [], + 'props': [], + 'commands': [], + 'state': [ + { + 'name': 'array_boolean_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'BooleanTypeAnnotation' + } + } + }, + { + 'name': 'array_boolean_optional_key', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'BooleanTypeAnnotation' + } + } + }, + { + 'name': 'array_boolean_optional_value', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'BooleanTypeAnnotation' + } + } + }, + { + 'name': 'array_boolean_optional_both', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'BooleanTypeAnnotation' + } + } + }, + { + 'name': 'array_string_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'StringTypeAnnotation' + } + } + }, + { + 'name': 'array_string_optional_key', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'StringTypeAnnotation' + } + } + }, + { + 'name': 'array_string_optional_value', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'StringTypeAnnotation' + } + } + }, + { + 'name': 'array_string_optional_both', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'StringTypeAnnotation' + } + } + }, + { + 'name': 'array_double_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'DoubleTypeAnnotation' + } + } + }, + { + 'name': 'array_double_optional_key', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'DoubleTypeAnnotation' + } + } + }, + { + 'name': 'array_double_optional_value', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'DoubleTypeAnnotation' + } + } + }, + { + 'name': 'array_double_optional_both', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'DoubleTypeAnnotation' + } + } + }, + { + 'name': 'array_float_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'FloatTypeAnnotation' + } + } + }, + { + 'name': 'array_float_optional_key', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'FloatTypeAnnotation' + } + } + }, + { + 'name': 'array_float_optional_value', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'FloatTypeAnnotation' + } + } + }, + { + 'name': 'array_float_optional_both', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'FloatTypeAnnotation' + } + } + }, + { + 'name': 'array_int32_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'Int32TypeAnnotation' + } + } + }, + { + 'name': 'array_int32_optional_key', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'Int32TypeAnnotation' + } + } + }, + { + 'name': 'array_int32_optional_value', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'Int32TypeAnnotation' + } + } + }, + { + 'name': 'array_int32_optional_both', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'Int32TypeAnnotation' + } + } + }, + { + 'name': 'array_enum_optional_key', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'StringEnumTypeAnnotation', + 'default': 'small', + 'options': [ + 'small', + 'large' + ] + } + } + }, + { + 'name': 'array_enum_optional_both', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'StringEnumTypeAnnotation', + 'default': 'small', + 'options': [ + 'small', + 'large' + ] + } + } + }, + { + 'name': 'array_image_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'ImageSourcePrimitive' + } + } + }, + { + 'name': 'array_image_optional_key', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'ImageSourcePrimitive' + } + } + }, + { + 'name': 'array_image_optional_value', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'ImageSourcePrimitive' + } + } + }, + { + 'name': 'array_image_optional_both', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'ImageSourcePrimitive' + } + } + }, + { + 'name': 'array_color_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'ColorPrimitive' + } + } + }, + { + 'name': 'array_color_optional_key', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'ColorPrimitive' + } + } + }, + { + 'name': 'array_color_optional_value', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'ColorPrimitive' + } + } + }, + { + 'name': 'array_color_optional_both', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'ColorPrimitive' + } + } + }, + { + 'name': 'array_point_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'PointPrimitive' + } + } + }, + { + 'name': 'array_point_optional_key', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'PointPrimitive' + } + } + }, + { + 'name': 'array_point_optional_value', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'PointPrimitive' + } + } + }, + { + 'name': 'array_point_optional_both', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'PointPrimitive' + } + } + }, + { + 'name': 'array_insets_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'EdgeInsetsPrimitive' + } + } + }, + { + 'name': 'array_insets_optional_key', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'EdgeInsetsPrimitive' + } + } + }, + { + 'name': 'array_insets_optional_value', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'EdgeInsetsPrimitive' + } + } + }, + { + 'name': 'array_insets_optional_both', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'EdgeInsetsPrimitive' + } + } + }, + { + 'name': 'array_object_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': false, + 'typeAnnotation': { + 'type': 'StringTypeAnnotation', + 'default': null + } + } + ] + } + } + }, + { + 'name': 'array_object_optional_key', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': false, + 'typeAnnotation': { + 'type': 'StringTypeAnnotation', + 'default': null + } + } + ] + } + } + }, + { + 'name': 'array_object_optional_value', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': false, + 'typeAnnotation': { + 'type': 'StringTypeAnnotation', + 'default': null + } + } + ] + } + } + }, + { + 'name': 'array_object_optional_both', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': false, + 'typeAnnotation': { + 'type': 'StringTypeAnnotation', + 'default': null + } + } + ] + } + } + }, + { + 'name': 'array_of_array_object_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'array_object_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': false, + 'typeAnnotation': { + 'type': 'StringTypeAnnotation', + 'default': null + } + } + ] + } + } + } + ] + } + } + }, + { + 'name': 'array_of_array_object_optional_key', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'array_object_optional_key', + 'optional': false, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': true, + 'typeAnnotation': { + 'type': 'StringTypeAnnotation', + 'default': null + } + } + ] + } + } + } + ] + } + } + }, + { + 'name': 'array_of_array_object_optional_value', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'array_object_optional_value', + 'optional': false, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': true, + 'typeAnnotation': { + 'type': 'StringTypeAnnotation', + 'default': null + } + } + ] + } + } + } + ] + } + } + }, + { + 'name': 'array_of_array_object_optional_both', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'array_object_optional_both', + 'optional': false, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': true, + 'typeAnnotation': { + 'type': 'StringTypeAnnotation', + 'default': null + } + } + ] + } + } + } + ] + } + } + }, + { + 'name': 'array_of_array_of_object_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': false, + 'typeAnnotation': { + 'type': 'StringTypeAnnotation', + 'default': null + } + } + ] + } + } + } + }, + { + 'name': 'array_of_array_of_object_required_in_file', + 'optional': false, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': false, + 'typeAnnotation': { + 'type': 'StringTypeAnnotation', + 'default': null + } + } + ] + } + } + } + }, + { + '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 + } + } + ] + } + } + } + } + ] + } + } + } + } +}" +`; + +exports[`RN Codegen Flow Parser can generate fixture COMMANDS_DEFINED_WITH_ALL_TYPES 1`] = ` +"{ + 'modules': { + 'Module': { + 'type': 'Component', + 'components': { + 'Module': { + 'extendsProps': [ + { + 'type': 'ReactNativeBuiltInType', + 'knownTypeName': 'ReactNativeCoreViewProps' + } + ], + 'events': [], + 'props': [], + 'commands': [ + { + 'name': 'handleRootTag', + 'optional': false, + 'typeAnnotation': { + 'type': 'FunctionTypeAnnotation', + 'params': [ + { + 'name': 'rootTag', + 'typeAnnotation': { + 'type': 'ReservedTypeAnnotation', + 'name': 'RootTag' + } + } + ], + 'returnTypeAnnotation': { + 'type': 'VoidTypeAnnotation' + } + } + }, + { + 'name': 'hotspotUpdate', + 'optional': false, + 'typeAnnotation': { + 'type': 'FunctionTypeAnnotation', + 'params': [ + { + 'name': 'x', + 'typeAnnotation': { + 'type': 'Int32TypeAnnotation' + } + }, + { + 'name': 'y', + 'typeAnnotation': { + 'type': 'Int32TypeAnnotation' + } + } + ], + 'returnTypeAnnotation': { + 'type': 'VoidTypeAnnotation' + } + } + }, + { + 'name': 'scrollTo', + 'optional': false, + 'typeAnnotation': { + 'type': 'FunctionTypeAnnotation', + 'params': [ + { + 'name': 'x', + 'typeAnnotation': { + 'type': 'FloatTypeAnnotation' + } + }, + { + 'name': 'y', + 'typeAnnotation': { + 'type': 'Int32TypeAnnotation' + } + }, + { + 'name': 'z', + 'typeAnnotation': { + 'type': 'DoubleTypeAnnotation' + } + }, + { + 'name': 'animated', + 'typeAnnotation': { + 'type': 'BooleanTypeAnnotation' + } + } + ], + 'returnTypeAnnotation': { + 'type': 'VoidTypeAnnotation' + } + } + } + ] + } + } + } + } +}" +`; + +exports[`RN Codegen Flow Parser can generate fixture COMMANDS_EVENTS_STATE_TYPES_EXPORTED 1`] = ` +"{ + 'modules': { + 'Module': { + 'type': 'Component', + 'components': { + 'Module': { + 'extendsProps': [ + { + 'type': 'ReactNativeBuiltInType', + 'knownTypeName': 'ReactNativeCoreViewProps' + } + ], + 'events': [ + { + 'name': 'onBubblingEventDefinedInline', + 'optional': false, + 'bubblingType': 'bubble', + 'typeAnnotation': { + 'type': 'EventTypeAnnotation', + 'argument': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'boolean_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'BooleanTypeAnnotation' + } + }, + { + 'name': 'boolean_optional_key', + 'optional': true, + 'typeAnnotation': { + 'type': 'BooleanTypeAnnotation' + } + }, + { + 'name': 'boolean_optional_value', + 'optional': true, + 'typeAnnotation': { + 'type': 'BooleanTypeAnnotation' + } + }, + { + 'name': 'boolean_optional_both', + 'optional': true, + 'typeAnnotation': { + 'type': 'BooleanTypeAnnotation' + } + }, + { + 'name': 'string_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'StringTypeAnnotation' + } + }, + { + 'name': 'string_optional_key', + 'optional': true, + 'typeAnnotation': { + 'type': 'StringTypeAnnotation' + } + }, + { + 'name': 'string_optional_value', + 'optional': true, + 'typeAnnotation': { + 'type': 'StringTypeAnnotation' + } + }, + { + 'name': 'string_optional_both', + 'optional': true, + 'typeAnnotation': { + 'type': 'StringTypeAnnotation' + } + }, + { + 'name': 'double_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'DoubleTypeAnnotation' + } + }, + { + 'name': 'double_optional_key', + 'optional': true, + 'typeAnnotation': { 'type': 'DoubleTypeAnnotation' } }, @@ -2811,107 +4162,30 @@ exports[`RN Codegen Flow Parser can generate fixture COMMANDS_AND_EVENTS_TYPES_E } } } - ] - } - } - } - } -}" -`; - -exports[`RN Codegen Flow Parser can generate fixture COMMANDS_DEFINED_WITH_ALL_TYPES 1`] = ` -"{ - 'modules': { - 'Module': { - 'type': 'Component', - 'components': { - 'Module': { - 'extendsProps': [ - { - 'type': 'ReactNativeBuiltInType', - 'knownTypeName': 'ReactNativeCoreViewProps' - } ], - 'events': [], - 'props': [], - 'commands': [ + 'state': [ { - 'name': 'handleRootTag', + 'name': 'boolean_required', 'optional': false, 'typeAnnotation': { - 'type': 'FunctionTypeAnnotation', - 'params': [ - { - 'name': 'rootTag', - 'typeAnnotation': { - 'type': 'ReservedTypeAnnotation', - 'name': 'RootTag' - } - } - ], - 'returnTypeAnnotation': { - 'type': 'VoidTypeAnnotation' - } + 'type': 'BooleanTypeAnnotation', + 'default': false } }, { - 'name': 'hotspotUpdate', - 'optional': false, + 'name': 'boolean_optional_key', + 'optional': true, 'typeAnnotation': { - 'type': 'FunctionTypeAnnotation', - 'params': [ - { - 'name': 'x', - 'typeAnnotation': { - 'type': 'Int32TypeAnnotation' - } - }, - { - 'name': 'y', - 'typeAnnotation': { - 'type': 'Int32TypeAnnotation' - } - } - ], - 'returnTypeAnnotation': { - 'type': 'VoidTypeAnnotation' - } + 'type': 'BooleanTypeAnnotation', + 'default': true } }, { - 'name': 'scrollTo', - 'optional': false, + 'name': 'boolean_optional_both', + 'optional': true, 'typeAnnotation': { - 'type': 'FunctionTypeAnnotation', - 'params': [ - { - 'name': 'x', - 'typeAnnotation': { - 'type': 'FloatTypeAnnotation' - } - }, - { - 'name': 'y', - 'typeAnnotation': { - 'type': 'Int32TypeAnnotation' - } - }, - { - 'name': 'z', - 'typeAnnotation': { - 'type': 'DoubleTypeAnnotation' - } - }, - { - 'name': 'animated', - 'typeAnnotation': { - 'type': 'BooleanTypeAnnotation' - } - } - ], - 'returnTypeAnnotation': { - 'type': 'VoidTypeAnnotation' - } + 'type': 'BooleanTypeAnnotation', + 'default': true } } ] @@ -6663,257 +7937,943 @@ exports[`RN Codegen Flow Parser can generate fixture EVENTS_DEFINED_INLINE_WITH_ } }, { - 'name': 'int32_optional_key', + 'name': 'int32_optional_key', + 'optional': true, + 'typeAnnotation': { + 'type': 'Int32TypeAnnotation' + } + }, + { + 'name': 'int32_optional_value', + 'optional': true, + 'typeAnnotation': { + 'type': 'Int32TypeAnnotation' + } + }, + { + 'name': 'int32_optional_both', + 'optional': true, + 'typeAnnotation': { + 'type': 'Int32TypeAnnotation' + } + }, + { + 'name': 'enum_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'StringEnumTypeAnnotation', + 'options': [ + 'small', + 'large' + ] + } + }, + { + 'name': 'enum_optional_key', + 'optional': true, + 'typeAnnotation': { + 'type': 'StringEnumTypeAnnotation', + 'options': [ + 'small', + 'large' + ] + } + }, + { + 'name': 'enum_optional_value', + 'optional': true, + 'typeAnnotation': { + 'type': 'StringEnumTypeAnnotation', + 'options': [ + 'small', + 'large' + ] + } + }, + { + 'name': 'enum_optional_both', + 'optional': true, + 'typeAnnotation': { + 'type': 'StringEnumTypeAnnotation', + 'options': [ + 'small', + 'large' + ] + } + }, + { + 'name': 'object_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'boolean_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'BooleanTypeAnnotation' + } + } + ] + } + }, + { + 'name': 'object_optional_key', + 'optional': true, + 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'string_optional_key', + 'optional': true, + 'typeAnnotation': { + 'type': 'StringTypeAnnotation' + } + } + ] + } + }, + { + 'name': 'object_optional_value', 'optional': true, 'typeAnnotation': { - 'type': 'Int32TypeAnnotation' + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'float_optional_value', + 'optional': true, + 'typeAnnotation': { + 'type': 'FloatTypeAnnotation' + } + } + ] } }, { - 'name': 'int32_optional_value', + 'name': 'object_optional_both', 'optional': true, 'typeAnnotation': { - 'type': 'Int32TypeAnnotation' + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'int32_optional_both', + 'optional': true, + 'typeAnnotation': { + 'type': 'Int32TypeAnnotation' + } + } + ] } }, { - 'name': 'int32_optional_both', - 'optional': true, + 'name': 'object_required_nested_2_layers', + 'optional': false, 'typeAnnotation': { - 'type': 'Int32TypeAnnotation' + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'object_optional_nested_1_layer', + 'optional': true, + 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'boolean_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'Int32TypeAnnotation' + } + }, + { + 'name': 'string_optional_key', + 'optional': true, + 'typeAnnotation': { + 'type': 'StringTypeAnnotation' + } + }, + { + 'name': 'double_optional_value', + 'optional': true, + 'typeAnnotation': { + 'type': 'DoubleTypeAnnotation' + } + }, + { + 'name': 'float_optional_value', + 'optional': true, + 'typeAnnotation': { + 'type': 'FloatTypeAnnotation' + } + }, + { + 'name': 'int32_optional_both', + 'optional': true, + 'typeAnnotation': { + 'type': 'Int32TypeAnnotation' + } + } + ] + } + } + ] } }, { - 'name': 'enum_required', + 'name': 'object_readonly_required', 'optional': false, 'typeAnnotation': { - 'type': 'StringEnumTypeAnnotation', - 'options': [ - 'small', - 'large' + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'boolean_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'BooleanTypeAnnotation' + } + } ] } }, { - 'name': 'enum_optional_key', + 'name': 'object_readonly_optional_key', 'optional': true, 'typeAnnotation': { - 'type': 'StringEnumTypeAnnotation', - 'options': [ - 'small', - 'large' + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'string_optional_key', + 'optional': true, + 'typeAnnotation': { + 'type': 'StringTypeAnnotation' + } + } ] } }, { - 'name': 'enum_optional_value', + 'name': 'object_readonly_optional_value', 'optional': true, 'typeAnnotation': { - 'type': 'StringEnumTypeAnnotation', - 'options': [ - 'small', - 'large' + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'float_optional_value', + 'optional': true, + 'typeAnnotation': { + 'type': 'FloatTypeAnnotation' + } + } ] } }, { - 'name': 'enum_optional_both', + 'name': 'object_readonly_optional_both', 'optional': true, 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'int32_optional_both', + 'optional': true, + 'typeAnnotation': { + 'type': 'Int32TypeAnnotation' + } + } + ] + } + } + ] + } + } + } + ], + 'props': [], + 'commands': [] + } + } + } + } +}" +`; + +exports[`RN Codegen Flow Parser can generate fixture NO_PROPS_EVENTS_ONLY_DEPRECATED_VIEW_CONFIG_NAME_OPTION 1`] = ` +"{ + 'modules': { + 'Module': { + 'type': 'Component', + 'components': { + 'Module': { + 'deprecatedViewConfigName': 'DeprecateModuleName', + 'extendsProps': [ + { + 'type': 'ReactNativeBuiltInType', + 'knownTypeName': 'ReactNativeCoreViewProps' + } + ], + 'events': [], + 'props': [], + 'commands': [] + } + } + } + } +}" +`; + +exports[`RN Codegen Flow Parser can generate fixture OBJECT_PROP_TYPES_NO_EVENTS 1`] = ` +"{ + 'modules': { + 'Module': { + 'type': 'Component', + 'components': { + 'Module': { + 'extendsProps': [ + { + 'type': 'ReactNativeBuiltInType', + 'knownTypeName': 'ReactNativeCoreViewProps' + } + ], + 'events': [], + 'props': [ + { + 'name': 'boolean_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': false, + 'typeAnnotation': { + 'type': 'BooleanTypeAnnotation', + 'default': false + } + } + ] + } + }, + { + 'name': 'boolean_optional', + 'optional': false, + 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': true, + 'typeAnnotation': { + 'type': 'BooleanTypeAnnotation', + 'default': false + } + } + ] + } + }, + { + 'name': 'string_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': false, + 'typeAnnotation': { + 'type': 'StringTypeAnnotation', + 'default': null + } + } + ] + } + }, + { + 'name': 'string_optional', + 'optional': false, + 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': true, + 'typeAnnotation': { + 'type': 'StringTypeAnnotation', + 'default': '' + } + } + ] + } + }, + { + 'name': 'double_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': false, + 'typeAnnotation': { + 'type': 'DoubleTypeAnnotation', + 'default': 0 + } + } + ] + } + }, + { + 'name': 'double_optional', + 'optional': false, + 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': true, + 'typeAnnotation': { + 'type': 'DoubleTypeAnnotation', + 'default': 0 + } + } + ] + } + }, + { + 'name': 'float_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': false, + 'typeAnnotation': { + 'type': 'FloatTypeAnnotation', + 'default': 0 + } + } + ] + } + }, + { + 'name': 'float_optional', + 'optional': false, + 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': true, + 'typeAnnotation': { + 'type': 'FloatTypeAnnotation', + 'default': 0 + } + } + ] + } + }, + { + 'name': 'int_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': false, + 'typeAnnotation': { + 'type': 'Int32TypeAnnotation', + 'default': 0 + } + } + ] + } + }, + { + 'name': 'int_optional', + 'optional': false, + 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': true, + 'typeAnnotation': { + 'type': 'Int32TypeAnnotation', + 'default': 0 + } + } + ] + } + }, + { + 'name': 'enum_optional', + 'optional': false, + 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': true, + 'typeAnnotation': { + 'type': 'ArrayTypeAnnotation', + 'elementType': { 'type': 'StringEnumTypeAnnotation', + 'default': 'small', 'options': [ 'small', 'large' ] } - }, - { - 'name': 'object_required', - 'optional': false, - 'typeAnnotation': { - 'type': 'ObjectTypeAnnotation', - 'properties': [ - { - 'name': 'boolean_required', - 'optional': false, - 'typeAnnotation': { - 'type': 'BooleanTypeAnnotation' - } - } - ] - } - }, - { - 'name': 'object_optional_key', - 'optional': true, - 'typeAnnotation': { - 'type': 'ObjectTypeAnnotation', - 'properties': [ - { - 'name': 'string_optional_key', - 'optional': true, - 'typeAnnotation': { - 'type': 'StringTypeAnnotation' - } - } - ] - } - }, - { - 'name': 'object_optional_value', - 'optional': true, - 'typeAnnotation': { - 'type': 'ObjectTypeAnnotation', - 'properties': [ - { - 'name': 'float_optional_value', - 'optional': true, - 'typeAnnotation': { - 'type': 'FloatTypeAnnotation' - } - } - ] - } - }, - { - 'name': 'object_optional_both', - 'optional': true, - 'typeAnnotation': { - 'type': 'ObjectTypeAnnotation', - 'properties': [ - { - 'name': 'int32_optional_both', - 'optional': true, - 'typeAnnotation': { - 'type': 'Int32TypeAnnotation' - } - } - ] - } - }, - { - 'name': 'object_required_nested_2_layers', - 'optional': false, - 'typeAnnotation': { - 'type': 'ObjectTypeAnnotation', - 'properties': [ - { - 'name': 'object_optional_nested_1_layer', - 'optional': true, - 'typeAnnotation': { - 'type': 'ObjectTypeAnnotation', - 'properties': [ - { - 'name': 'boolean_required', - 'optional': false, - 'typeAnnotation': { - 'type': 'Int32TypeAnnotation' - } - }, - { - 'name': 'string_optional_key', - 'optional': true, - 'typeAnnotation': { - 'type': 'StringTypeAnnotation' - } - }, - { - 'name': 'double_optional_value', - 'optional': true, - 'typeAnnotation': { - 'type': 'DoubleTypeAnnotation' - } - }, - { - 'name': 'float_optional_value', - 'optional': true, - 'typeAnnotation': { - 'type': 'FloatTypeAnnotation' - } - }, - { - 'name': 'int32_optional_both', - 'optional': true, - 'typeAnnotation': { - 'type': 'Int32TypeAnnotation' - } - } - ] - } - } - ] - } - }, - { - 'name': 'object_readonly_required', - 'optional': false, - 'typeAnnotation': { - 'type': 'ObjectTypeAnnotation', - 'properties': [ - { - 'name': 'boolean_required', - 'optional': false, - 'typeAnnotation': { - 'type': 'BooleanTypeAnnotation' - } + } + } + ] + } + }, + { + 'name': 'image_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': false, + 'typeAnnotation': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'ImageSourcePrimitive' + } + } + ] + } + }, + { + 'name': 'image_optional_key', + 'optional': false, + 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': true, + 'typeAnnotation': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'ImageSourcePrimitive' + } + } + ] + } + }, + { + 'name': 'image_optional_value', + 'optional': false, + 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': true, + 'typeAnnotation': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'ImageSourcePrimitive' + } + } + ] + } + }, + { + 'name': 'image_optional_both', + 'optional': false, + 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': true, + 'typeAnnotation': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'ImageSourcePrimitive' + } + } + ] + } + }, + { + 'name': 'color_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': false, + 'typeAnnotation': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'ColorPrimitive' + } + } + ] + } + }, + { + 'name': 'color_optional_key', + 'optional': false, + 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': true, + 'typeAnnotation': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'ColorPrimitive' + } + } + ] + } + }, + { + 'name': 'color_optional_value', + 'optional': false, + 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': true, + 'typeAnnotation': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'ColorPrimitive' + } + } + ] + } + }, + { + 'name': 'color_optional_both', + 'optional': false, + 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': true, + 'typeAnnotation': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'ColorPrimitive' + } + } + ] + } + }, + { + 'name': 'processed_color_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': false, + 'typeAnnotation': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'ColorPrimitive' + } + } + ] + } + }, + { + 'name': 'processed_color_optional_key', + 'optional': false, + 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': true, + 'typeAnnotation': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'ColorPrimitive' + } + } + ] + } + }, + { + 'name': 'processed_color_optional_value', + 'optional': false, + 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': true, + 'typeAnnotation': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'ColorPrimitive' + } + } + ] + } + }, + { + 'name': 'processed_color_optional_both', + 'optional': false, + 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': true, + 'typeAnnotation': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'ColorPrimitive' + } + } + ] + } + }, + { + 'name': 'point_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': false, + 'typeAnnotation': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'PointPrimitive' + } + } + ] + } + }, + { + 'name': 'point_optional_key', + 'optional': false, + 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': true, + 'typeAnnotation': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'PointPrimitive' + } + } + ] + } + }, + { + 'name': 'point_optional_value', + 'optional': false, + 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': true, + 'typeAnnotation': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'PointPrimitive' + } + } + ] + } + }, + { + 'name': 'point_optional_both', + 'optional': false, + 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': true, + 'typeAnnotation': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'PointPrimitive' + } + } + ] + } + }, + { + 'name': 'insets_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': false, + 'typeAnnotation': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'EdgeInsetsPrimitive' + } + } + ] + } + }, + { + 'name': 'insets_optional_key', + 'optional': false, + 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': true, + 'typeAnnotation': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'EdgeInsetsPrimitive' + } + } + ] + } + }, + { + 'name': 'insets_optional_value', + 'optional': false, + 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': true, + 'typeAnnotation': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'EdgeInsetsPrimitive' + } + } + ] + } + }, + { + 'name': 'insets_optional_both', + 'optional': false, + 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': true, + 'typeAnnotation': { + 'type': 'ReservedPropTypeAnnotation', + 'name': 'EdgeInsetsPrimitive' + } + } + ] + } + }, + { + 'name': 'object_required', + 'optional': false, + 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': false, + 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'nestedProp', + 'optional': false, + 'typeAnnotation': { + 'type': 'StringTypeAnnotation', + 'default': null } - ] - } - }, - { - 'name': 'object_readonly_optional_key', - 'optional': true, - 'typeAnnotation': { - 'type': 'ObjectTypeAnnotation', - 'properties': [ - { - 'name': 'string_optional_key', - 'optional': true, - 'typeAnnotation': { - 'type': 'StringTypeAnnotation' - } + } + ] + } + } + ] + } + }, + { + 'name': 'object_optional_key', + 'optional': true, + 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': false, + 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'nestedProp', + 'optional': false, + 'typeAnnotation': { + 'type': 'StringTypeAnnotation', + 'default': null } - ] - } - }, - { - 'name': 'object_readonly_optional_value', - 'optional': true, - 'typeAnnotation': { - 'type': 'ObjectTypeAnnotation', - 'properties': [ - { - 'name': 'float_optional_value', - 'optional': true, - 'typeAnnotation': { - 'type': 'FloatTypeAnnotation' - } + } + ] + } + } + ] + } + }, + { + 'name': 'object_optional_value', + 'optional': true, + 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': false, + 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'nestedProp', + 'optional': false, + 'typeAnnotation': { + 'type': 'StringTypeAnnotation', + 'default': null } - ] - } - }, - { - 'name': 'object_readonly_optional_both', - 'optional': true, - 'typeAnnotation': { - 'type': 'ObjectTypeAnnotation', - 'properties': [ - { - 'name': 'int32_optional_both', - 'optional': true, - 'typeAnnotation': { - 'type': 'Int32TypeAnnotation' - } + } + ] + } + } + ] + } + }, + { + 'name': 'object_optional_both', + 'optional': true, + 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'prop', + 'optional': false, + 'typeAnnotation': { + 'type': 'ObjectTypeAnnotation', + 'properties': [ + { + 'name': 'nestedProp', + 'optional': false, + 'typeAnnotation': { + 'type': 'StringTypeAnnotation', + 'default': null } - ] - } + } + ] } - ] - } + } + ] } } ], - 'props': [], 'commands': [] } } @@ -6922,14 +8882,13 @@ exports[`RN Codegen Flow Parser can generate fixture EVENTS_DEFINED_INLINE_WITH_ }" `; -exports[`RN Codegen Flow Parser can generate fixture NO_PROPS_EVENTS_ONLY_DEPRECATED_VIEW_CONFIG_NAME_OPTION 1`] = ` +exports[`RN Codegen Flow Parser can generate fixture OBJECT_STATE_TYPES 1`] = ` "{ 'modules': { 'Module': { 'type': 'Component', 'components': { 'Module': { - 'deprecatedViewConfigName': 'DeprecateModuleName', 'extendsProps': [ { 'type': 'ReactNativeBuiltInType', @@ -6938,29 +8897,8 @@ exports[`RN Codegen Flow Parser can generate fixture NO_PROPS_EVENTS_ONLY_DEPREC ], 'events': [], 'props': [], - 'commands': [] - } - } - } - } -}" -`; - -exports[`RN Codegen Flow Parser can generate fixture OBJECT_PROP_TYPES_NO_EVENTS 1`] = ` -"{ - 'modules': { - 'Module': { - 'type': 'Component', - 'components': { - 'Module': { - 'extendsProps': [ - { - 'type': 'ReactNativeBuiltInType', - 'knownTypeName': 'ReactNativeCoreViewProps' - } - ], - 'events': [], - 'props': [ + 'commands': [], + 'state': [ { 'name': 'boolean_required', 'optional': false, @@ -7599,8 +9537,7 @@ exports[`RN Codegen Flow Parser can generate fixture OBJECT_PROP_TYPES_NO_EVENTS ] } } - ], - 'commands': [] + ] } } } diff --git a/packages/react-native-codegen/src/parsers/flow/components/index.js b/packages/react-native-codegen/src/parsers/flow/components/index.js index e488635d94300e..2b90a0a5bddce6 100644 --- a/packages/react-native-codegen/src/parsers/flow/components/index.js +++ b/packages/react-native-codegen/src/parsers/flow/components/index.js @@ -16,6 +16,7 @@ import type {ComponentSchemaBuilderConfig} from './schema.js'; const {getTypes} = require('../utils'); const {getCommands} = require('./commands'); const {getEvents} = require('./events'); +const {getStateProperties, getState} = require('./states'); const {getExtendsProps, removeKnownExtends} = require('./extends'); const {getCommandOptions, getOptions} = require('./options'); const {getPropProperties, getProps} = require('./props'); @@ -111,8 +112,32 @@ function findComponentConfig(ast) { throw new Error('codegenNativeCommands may only be called once in a file'); } + const unexportedStateTypes: Array = ast.body + .filter( + node => + node.type === 'TypeAlias' && node.id.name.indexOf('NativeState') >= 0, + ) + .map(node => node.id.name); + + const exportedStateTypes: Array = namedExports + .filter( + node => + node.declaration.id && + node.declaration.id.name.indexOf('NativeState') >= 0, + ) + .map(node => node.declaration.id.name); + + const stateTypeName = exportedStateTypes.concat(unexportedStateTypes); + + if (Array.isArray(stateTypeName) && stateTypeName.length > 1) { + throw new Error( + `Found ${stateTypeName.length} NativeStates for ${foundConfig.componentName}. Each component can have only 1 NativeState`, + ); + } + return { ...foundConfig, + stateTypeName: stateTypeName[0], commandTypeName: commandsTypeNames[0] == null ? null @@ -185,6 +210,7 @@ function buildComponentSchema(ast): ComponentSchemaBuilderConfig { const { componentName, propsTypeName, + stateTypeName, commandTypeName, commandOptionsExpression, optionsExpression, @@ -209,7 +235,7 @@ function buildComponentSchema(ast): ComponentSchemaBuilderConfig { const events = getEvents(propProperties, types); const commands = getCommands(commandProperties, types); - return { + const toRet = { filename: componentName, componentName, options, @@ -218,6 +244,17 @@ function buildComponentSchema(ast): ComponentSchemaBuilderConfig { props, commands, }; + + if (stateTypeName) { + const stateProperties = getStateProperties(stateTypeName, types); + const state = getState(stateProperties, types); + return { + ...toRet, + state, + }; + } + + return toRet; } module.exports = { diff --git a/packages/react-native-codegen/src/parsers/flow/components/schema.js b/packages/react-native-codegen/src/parsers/flow/components/schema.js index ed6223c3347b50..e7bff107dbeba4 100644 --- a/packages/react-native-codegen/src/parsers/flow/components/schema.js +++ b/packages/react-native-codegen/src/parsers/flow/components/schema.js @@ -15,6 +15,7 @@ import type { NamedShape, CommandTypeAnnotation, PropTypeAnnotation, + StateTypeAnnotation, ExtendsPropsShape, SchemaType, OptionsShape, @@ -27,6 +28,7 @@ export type ComponentSchemaBuilderConfig = $ReadOnly<{ events: $ReadOnlyArray, props: $ReadOnlyArray>, commands: $ReadOnlyArray>, + state?: $ReadOnlyArray>, options?: ?OptionsShape, }>; @@ -36,6 +38,7 @@ function wrapComponentSchema({ extendsProps, events, props, + state, options, commands, }: ComponentSchemaBuilderConfig): SchemaType { @@ -50,6 +53,7 @@ function wrapComponentSchema({ events, props, commands, + state, }, }, }, diff --git a/packages/react-native-codegen/src/parsers/flow/components/states.js b/packages/react-native-codegen/src/parsers/flow/components/states.js new file mode 100644 index 00000000000000..987cc8a85adc31 --- /dev/null +++ b/packages/react-native-codegen/src/parsers/flow/components/states.js @@ -0,0 +1,493 @@ +/** + * 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 {ASTNode} from '../utils'; + +const {getValueFromTypes} = require('../utils.js'); + +import type {StateTypeAnnotation, NamedShape} from '../../../CodegenSchema.js'; +import type {TypeDeclarationMap} from '../utils.js'; + +function getStateProperties( + stateTypeName: string, + types: TypeDeclarationMap, +): $FlowFixMe { + const typeAlias = types[stateTypeName]; + try { + return typeAlias.right.typeParameters.params[0].properties; + } catch (e) { + throw new Error( + `Failed to find type definition for "${stateTypeName}", please check that you have a valid codegen flow file`, + ); + } +} + +function getTypeAnnotationForArray( + name: string, + typeAnnotation: $FlowFixMe, + defaultValue: $FlowFixMe | null, + types: TypeDeclarationMap, +) { + const extractedTypeAnnotation = getValueFromTypes(typeAnnotation, types); + if (extractedTypeAnnotation.type === 'NullableTypeAnnotation') { + throw new Error( + 'Nested optionals such as "$ReadOnlyArray" are not supported, please declare optionals at the top level of value definitions as in "?$ReadOnlyArray"', + ); + } + + if ( + extractedTypeAnnotation.type === 'GenericTypeAnnotation' && + extractedTypeAnnotation.id.name === 'WithDefault' + ) { + throw new Error( + 'Nested defaults such as "$ReadOnlyArray>" are not supported, please declare defaults at the top level of value definitions as in "WithDefault<$ReadOnlyArray, false>"', + ); + } + + if (extractedTypeAnnotation.type === 'GenericTypeAnnotation') { + // Resolve the type alias if it's not defined inline + const objectType = getValueFromTypes(extractedTypeAnnotation, types); + + if (objectType.id.name === '$ReadOnly') { + return { + type: 'ObjectTypeAnnotation', + properties: flattenProperties( + objectType.typeParameters.params[0].properties, + types, + ) + .map(prop => buildStateSchema(prop, types)) + .filter(Boolean), + }; + } + + if (objectType.id.name === '$ReadOnlyArray') { + // We need to go yet another level deeper to resolve + // types that may be defined in a type alias + const nestedObjectType = getValueFromTypes( + objectType.typeParameters.params[0], + types, + ); + + return { + type: 'ArrayTypeAnnotation', + elementType: { + type: 'ObjectTypeAnnotation', + properties: flattenProperties( + nestedObjectType.typeParameters.params[0].properties, + types, + ) + .map(prop => buildStateSchema(prop, types)) + .filter(Boolean), + }, + }; + } + } + + const type = + extractedTypeAnnotation.type === 'GenericTypeAnnotation' + ? extractedTypeAnnotation.id.name + : extractedTypeAnnotation.type; + + switch (type) { + case 'ImageSource': + return { + type: 'ReservedPropTypeAnnotation', + name: 'ImageSourcePrimitive', + }; + 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', + }; + case 'Int32': + return { + type: 'Int32TypeAnnotation', + }; + case 'Double': + return { + type: 'DoubleTypeAnnotation', + }; + case 'Float': + return { + type: 'FloatTypeAnnotation', + }; + case 'BooleanTypeAnnotation': + return { + type: 'BooleanTypeAnnotation', + }; + case 'StringTypeAnnotation': + return { + type: 'StringTypeAnnotation', + }; + case 'UnionTypeAnnotation': + typeAnnotation.types.reduce((lastType, currType) => { + if (lastType && currType.type !== lastType.type) { + throw new Error(`Mixed types are not supported (see "${name}").`); + } + return currType; + }); + + if (defaultValue === null) { + throw new Error(`A default enum value is required for "${name}"`); + } + + const unionType = typeAnnotation.types[0].type; + if (unionType === 'StringLiteralTypeAnnotation') { + return { + type: 'StringEnumTypeAnnotation', + default: (defaultValue: string), + options: typeAnnotation.types.map(option => option.value), + }; + } else if (unionType === 'NumberLiteralTypeAnnotation') { + throw new Error( + `Arrays of int enums are not supported (see: "${name}")`, + ); + } else { + throw new Error( + `Unsupported union type for "${name}", received "${unionType}"`, + ); + } + default: + (type: empty); + throw new Error( + `Unknown property type for "${name}": ${type} in the State`, + ); + } +} + +function getTypeAnnotation( + name: string, + annotation: $FlowFixMe | ASTNode, + defaultValue: $FlowFixMe | null, + withNullDefault: boolean, + types: TypeDeclarationMap, +) { + const typeAnnotation = getValueFromTypes(annotation, types); + + if ( + typeAnnotation.type === 'GenericTypeAnnotation' && + typeAnnotation.id.name === '$ReadOnlyArray' + ) { + return { + type: 'ArrayTypeAnnotation', + elementType: getTypeAnnotationForArray( + name, + typeAnnotation.typeParameters.params[0], + defaultValue, + types, + ), + }; + } + + if ( + typeAnnotation.type === 'GenericTypeAnnotation' && + typeAnnotation.id.name === '$ReadOnly' + ) { + return { + type: 'ObjectTypeAnnotation', + properties: flattenProperties( + typeAnnotation.typeParameters.params[0].properties, + types, + ) + .map(prop => buildStateSchema(prop, types)) + .filter(Boolean), + }; + } + + const type = + typeAnnotation.type === 'GenericTypeAnnotation' + ? typeAnnotation.id.name + : typeAnnotation.type; + + switch (type) { + case 'ImageSource': + return { + type: 'ReservedPropTypeAnnotation', + name: 'ImageSourcePrimitive', + }; + case 'ColorValue': + case 'ProcessedColorValue': + return { + type: 'ReservedPropTypeAnnotation', + name: 'ColorPrimitive', + }; + case 'ColorArrayValue': + return { + type: 'ArrayTypeAnnotation', + elementType: { + type: 'ReservedPropTypeAnnotation', + name: 'ColorPrimitive', + }, + }; + case 'PointValue': + return { + type: 'ReservedPropTypeAnnotation', + name: 'PointPrimitive', + }; + case 'EdgeInsetsValue': + return { + type: 'ReservedPropTypeAnnotation', + name: 'EdgeInsetsPrimitive', + }; + 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: withNullDefault + ? (defaultValue: number | null) + : ((defaultValue ? defaultValue : 0): number), + }; + case 'BooleanTypeAnnotation': + return { + type: 'BooleanTypeAnnotation', + default: withNullDefault + ? (defaultValue: boolean | null) + : ((defaultValue == null ? false : defaultValue): boolean), + }; + case 'StringTypeAnnotation': + if (typeof defaultValue !== 'undefined') { + return { + type: 'StringTypeAnnotation', + default: (defaultValue: string | null), + }; + } + throw new Error(`A default string (or null) is required for "${name}"`); + case 'Stringish': + if (typeof defaultValue !== 'undefined') { + return { + type: 'StringTypeAnnotation', + default: (defaultValue: string | null), + }; + } + throw new Error(`A default string (or null) is required for "${name}"`); + case 'UnionTypeAnnotation': + typeAnnotation.types.reduce((lastType, currType) => { + if (lastType && currType.type !== lastType.type) { + throw new Error(`Mixed types are not supported (see "${name}").`); + } + return currType; + }); + + if (defaultValue === null) { + throw new Error(`A default enum value is required for "${name}"`); + } + + const unionType = typeAnnotation.types[0].type; + if (unionType === 'StringLiteralTypeAnnotation') { + return { + type: 'StringEnumTypeAnnotation', + default: (defaultValue: string), + options: typeAnnotation.types.map(option => option.value), + }; + } else if (unionType === 'NumberLiteralTypeAnnotation') { + return { + type: 'Int32EnumTypeAnnotation', + default: (defaultValue: number), + options: typeAnnotation.types.map(option => option.value), + }; + } else { + throw new Error( + `Unsupported union type for "${name}", received "${unionType}"`, + ); + } + case 'ObjectTypeAnnotation': + throw new Error( + `Cannot use "${type}" type annotation for "${name}": object types must be declared using $ReadOnly<>`, + ); + case 'NumberTypeAnnotation': + throw new Error( + `Cannot use "${type}" type annotation for "${name}": must use a specific numeric type like Int32, Double, or Float`, + ); + default: + (type: empty); + throw new Error( + `Unknown property type for "${name}": "${type}" in the State`, + ); + } +} + +function buildStateSchema( + property: PropAST, + types: TypeDeclarationMap, +): ?NamedShape { + const name = property.key.name; + + const value = getValueFromTypes(property.value, types); + let typeAnnotation = + value.type === 'NullableTypeAnnotation' ? value.typeAnnotation : value; + + const optional = + value.type === 'NullableTypeAnnotation' || + property.optional || + (value.type === 'GenericTypeAnnotation' && + typeAnnotation.id.name === 'WithDefault'); + + if ( + !property.optional && + value.type === 'GenericTypeAnnotation' && + typeAnnotation.id.name === 'WithDefault' + ) { + throw new Error( + `key ${name} must be optional if used with WithDefault<> annotation`, + ); + } + if ( + value.type === 'NullableTypeAnnotation' && + typeAnnotation.type === 'GenericTypeAnnotation' && + typeAnnotation.id.name === 'WithDefault' + ) { + throw new Error( + 'WithDefault<> is optional and does not need to be marked as optional. Please remove the ? annotation in front of it.', + ); + } + + // Discard events, they should not be managed in the state + let type = typeAnnotation.type; + if ( + type === 'GenericTypeAnnotation' && + (typeAnnotation.id.name === 'DirectEventHandler' || + typeAnnotation.id.name === 'BubblingEventHandler') + ) { + return null; + } + + // Discard style, they should not be managed in the state + if ( + name === 'style' && + type === 'GenericTypeAnnotation' && + typeAnnotation.id.name === 'ViewStyleProp' + ) { + return null; + } + + let defaultValue = null; + let withNullDefault = false; + if ( + type === 'GenericTypeAnnotation' && + typeAnnotation.id.name === 'WithDefault' + ) { + if (typeAnnotation.typeParameters.params.length === 1) { + throw new Error( + `WithDefault requires two parameters, did you forget to provide a default value for "${name}"?`, + ); + } + + defaultValue = typeAnnotation.typeParameters.params[1].value; + const defaultValueType = typeAnnotation.typeParameters.params[1].type; + + typeAnnotation = typeAnnotation.typeParameters.params[0]; + type = + typeAnnotation.type === 'GenericTypeAnnotation' + ? typeAnnotation.id.name + : typeAnnotation.type; + + if (defaultValueType === 'NullLiteralTypeAnnotation') { + defaultValue = null; + withNullDefault = true; + } + } + + return { + name, + optional, + typeAnnotation: getTypeAnnotation( + name, + typeAnnotation, + defaultValue, + withNullDefault, + types, + ), + }; +} + +// $FlowFixMe[unclear-type] there's no flowtype for ASTs +type PropAST = Object; + +function verifyStateNotAlreadyDefined( + props: $ReadOnlyArray, + needleProp: PropAST, +) { + const propName = needleProp.key.name; + const foundProp = props.some(prop => prop.key.name === propName); + if (foundProp) { + throw new Error( + `A property was already defined with the name ${propName} in the State`, + ); + } +} + +function flattenProperties( + typeDefinition: $ReadOnlyArray, + types: TypeDeclarationMap, +) { + return typeDefinition + .map(property => { + if (property.type === 'ObjectTypeProperty') { + return property; + } else if (property.type === 'ObjectTypeSpreadProperty') { + return flattenProperties( + getStateProperties(property.argument.id.name, types), + types, + ); + } + }) + .reduce((acc, item) => { + if (Array.isArray(item)) { + item.forEach(state => { + verifyStateNotAlreadyDefined(acc, state); + }); + return acc.concat(item); + } else { + verifyStateNotAlreadyDefined(acc, item); + acc.push(item); + return acc; + } + }, []) + .filter(Boolean); +} + +function getState( + typeDefinition: $ReadOnlyArray, + types: TypeDeclarationMap, +): $ReadOnlyArray> { + return flattenProperties(typeDefinition, types) + .map(property => buildStateSchema(property, types)) + .filter(Boolean); +} + +module.exports = { + getState, + getStateProperties, +};