From f3c98c5fa273dbdb17c32cd1193a3f078ef942b4 Mon Sep 17 00:00:00 2001 From: Riccardo Cipolleschi Date: Fri, 30 Sep 2022 04:02:48 -0700 Subject: [PATCH] Handle properly negative values in TS parser (#34800) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/34800 The TypeScript parser was not handling negative default values properly. The reason why is because the AST for those values is structurally different and wraps them in a `UnaryExpression` with the `-` operator. This Diff adds the support for those default values and it also add some tests in both Flow and TS. ## Changelog [General][Fixed] - Properly parse negative values Reviewed By: cortinico Differential Revision: D39847784 fbshipit-source-id: 95fc5768987477c540a54a7c4e4ff785d7a1e5d7 --- .../components/__test_fixtures__/fixtures.js | 42 ++++++++++++ .../component-parser-test.js.snap | 65 +++++++++++++++++++ .../components/__test_fixtures__/fixtures.js | 45 +++++++++++++ .../typescript-component-parser-test.js.snap | 65 +++++++++++++++++++ .../typescript/components/componentsUtils.js | 9 +++ 5 files changed, 226 insertions(+) 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 41ac2e97093c73..9517a4c96bdeb5 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 @@ -1073,6 +1073,10 @@ type ModuleNativeState = $ReadOnly<{| float_null_optional_key?: WithDefault, float_null_optional_both?: WithDefault, + // Float props, negative default + negative_float_optional_key?: WithDefault; + negative_float_optional_both?: WithDefault; + // Int32 props int32_required: Int32, int32_optional_key?: WithDefault, @@ -1131,6 +1135,43 @@ export default (codegenNativeComponent( ): HostComponent); `; +const STATE_NEGATIVE_DEFAULTS = ` +/** + * 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 + */ + +'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 ModuleProps = $ReadOnly<{| + ...ViewProps, +|}>; + +type ModuleNativeState = $ReadOnly<{| + + // Negative numbers default + negative_float_optional_key?: WithDefault; + negative_int_optional_key?: WithDefault; + negative_double_optional_key?: WithDefault; +|}> + +export default codegenNativeComponent( + 'Module', +) as HostComponent; +`; + const ARRAY_STATE_TYPES = ` /** * Copyright (c) Meta Platforms, Inc. and affiliates. @@ -1446,5 +1487,6 @@ module.exports = { ALL_STATE_TYPES, ARRAY_STATE_TYPES, OBJECT_STATE_TYPES, + STATE_NEGATIVE_DEFAULTS, // 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 53a72ca7ac269e..2d3b92f835c4a7 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 @@ -774,6 +774,22 @@ exports[`RN Codegen Flow Parser can generate fixture ALL_STATE_TYPES 1`] = ` 'default': null } }, + { + 'name': 'negative_float_optional_key', + 'optional': true, + 'typeAnnotation': { + 'type': 'FloatTypeAnnotation', + 'default': -1 + } + }, + { + 'name': 'negative_float_optional_both', + 'optional': true, + 'typeAnnotation': { + 'type': 'FloatTypeAnnotation', + 'default': -1 + } + }, { 'name': 'int32_required', 'optional': false, @@ -11357,3 +11373,52 @@ exports[`RN Codegen Flow Parser can generate fixture PROPS_AS_EXTERNAL_TYPES 1`] } }" `; + +exports[`RN Codegen Flow Parser can generate fixture STATE_NEGATIVE_DEFAULTS 1`] = ` +"{ + 'modules': { + 'Module': { + 'type': 'Component', + 'components': { + 'Module': { + 'extendsProps': [ + { + 'type': 'ReactNativeBuiltInType', + 'knownTypeName': 'ReactNativeCoreViewProps' + } + ], + 'events': [], + 'props': [], + 'commands': [], + 'state': [ + { + 'name': 'negative_float_optional_key', + 'optional': true, + 'typeAnnotation': { + 'type': 'FloatTypeAnnotation', + 'default': -1 + } + }, + { + 'name': 'negative_int_optional_key', + 'optional': true, + 'typeAnnotation': { + 'type': 'Int32TypeAnnotation', + 'default': -1 + } + }, + { + 'name': 'negative_double_optional_key', + 'optional': true, + 'typeAnnotation': { + 'type': 'DoubleTypeAnnotation', + 'default': -1 + } + } + ] + } + } + } + } +}" +`; diff --git a/packages/react-native-codegen/src/parsers/typescript/components/__test_fixtures__/fixtures.js b/packages/react-native-codegen/src/parsers/typescript/components/__test_fixtures__/fixtures.js index 0d31512d373f5d..728afa8ec6b310 100644 --- a/packages/react-native-codegen/src/parsers/typescript/components/__test_fixtures__/fixtures.js +++ b/packages/react-native-codegen/src/parsers/typescript/components/__test_fixtures__/fixtures.js @@ -1209,6 +1209,10 @@ export interface ModuleNativeState { float_null_optional_key?: WithDefault; float_null_optional_both?: WithDefault; + // Float props, negative default + negative_float_optional_key?: WithDefault; + negative_float_optional_both?: WithDefault; + // Int32 props int32_required: Int32; int32_optional_key?: WithDefault; @@ -1267,6 +1271,46 @@ export default codegenNativeComponent( ) as HostComponent; `; +const STATE_NEGATIVE_DEFAULTS = ` +/** + * 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 + */ + +'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'; + +export interface ModuleProps extends ViewProps { } + +export interface ModuleNativeState { + + // Negative numbers default + negative_float_optional_key?: WithDefault; + negative_int_optional_key?: WithDefault; + negative_double_optional_key?: WithDefault; +} + +export default codegenNativeComponent( + 'Module', +) as HostComponent; +`; + const ARRAY_STATE_TYPES = ` /** * Copyright (c) Meta Platforms, Inc. and affiliates. @@ -1678,4 +1722,5 @@ module.exports = { ARRAY_STATE_TYPES, ARRAY2_STATE_TYPES, OBJECT_STATE_TYPES, + STATE_NEGATIVE_DEFAULTS, }; diff --git a/packages/react-native-codegen/src/parsers/typescript/components/__tests__/__snapshots__/typescript-component-parser-test.js.snap b/packages/react-native-codegen/src/parsers/typescript/components/__tests__/__snapshots__/typescript-component-parser-test.js.snap index 5d20c9daeaee12..09ecbc5643aab8 100644 --- a/packages/react-native-codegen/src/parsers/typescript/components/__tests__/__snapshots__/typescript-component-parser-test.js.snap +++ b/packages/react-native-codegen/src/parsers/typescript/components/__tests__/__snapshots__/typescript-component-parser-test.js.snap @@ -770,6 +770,22 @@ exports[`RN Codegen TypeScript Parser can generate fixture ALL_STATE_TYPES 1`] = 'default': null } }, + { + 'name': 'negative_float_optional_key', + 'optional': true, + 'typeAnnotation': { + 'type': 'FloatTypeAnnotation', + 'default': -1 + } + }, + { + 'name': 'negative_float_optional_both', + 'optional': true, + 'typeAnnotation': { + 'type': 'FloatTypeAnnotation', + 'default': -1 + } + }, { 'name': 'int32_required', 'optional': false, @@ -12987,3 +13003,52 @@ exports[`RN Codegen TypeScript Parser can generate fixture PROPS_AS_EXTERNAL_TYP } }" `; + +exports[`RN Codegen TypeScript Parser can generate fixture STATE_NEGATIVE_DEFAULTS 1`] = ` +"{ + 'modules': { + 'Module': { + 'type': 'Component', + 'components': { + 'Module': { + 'extendsProps': [ + { + 'type': 'ReactNativeBuiltInType', + 'knownTypeName': 'ReactNativeCoreViewProps' + } + ], + 'events': [], + 'props': [], + 'commands': [], + 'state': [ + { + 'name': 'negative_float_optional_key', + 'optional': true, + 'typeAnnotation': { + 'type': 'FloatTypeAnnotation', + 'default': -1 + } + }, + { + 'name': 'negative_int_optional_key', + 'optional': true, + 'typeAnnotation': { + 'type': 'Int32TypeAnnotation', + 'default': -1 + } + }, + { + 'name': 'negative_double_optional_key', + 'optional': true, + 'typeAnnotation': { + 'type': 'DoubleTypeAnnotation', + 'default': -1 + } + } + ] + } + } + } + } +}" +`; diff --git a/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js b/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js index bd046a068d0428..e9b9888c497b27 100644 --- a/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js +++ b/packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js @@ -637,6 +637,15 @@ function getSchemaInfo( if (defaultValueType === 'TSLiteralType') { defaultValueType = typeAnnotation.typeParameters.params[1].literal.type; defaultValue = typeAnnotation.typeParameters.params[1].literal.value; + if ( + defaultValueType === 'UnaryExpression' && + typeAnnotation.typeParameters.params[1].literal.argument.type === + 'NumericLiteral' && + typeAnnotation.typeParameters.params[1].literal.operator === '-' + ) { + defaultValue = + -1 * typeAnnotation.typeParameters.params[1].literal.argument.value; + } } if (defaultValueType === 'TSNullKeyword') {