Move getCommandOptions and getOptions to parsers commons (#36413)

Summary:
> [Codegen 92] The getCommandOptions function in parsers/typescript/components/options.js and parsers/flow/components/options.js is the same. move it in parser-commons and use it in the original files. If the file two options.js files are empty, delete them.

> [Codegen 93] The getOptions function in parsers/typescript/components/options.js and parsers/flow/components/options.js is the same. move it in parser-commons and use it in the original files. If the file two options.js files are empty, delete them.

Part of Issue https://github.com/facebook/react-native/issues/34872

## Changelog:

<!-- Help reviewers and the release process by writing your own changelog entry.

Pick one each for the category and type tags:

[ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message

For more details, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->
[Internal][Changed] - Move getCommandOptions and getOptions to parsers commons from parsers components options

Pull Request resolved: https://github.com/facebook/react-native/pull/36413

Test Plan: `yarn jest react-native-codegen`

Reviewed By: rshest

Differential Revision: D43957023

Pulled By: cipolleschi

fbshipit-source-id: 4f8bf6f8fe69b20d0fb976afee7da244ef634e12
This commit is contained in:
Tarun Chauhan
2023-03-20 07:32:14 -07:00
committed by Facebook GitHub Bot
parent 2f25261b88
commit 221aacd72d
6 changed files with 210 additions and 178 deletions
@@ -21,6 +21,8 @@ import {
buildSchema,
parseModuleName,
createComponentConfig,
getCommandOptions,
getOptions,
} from '../parsers-commons';
import type {ParserType} from '../errors';
@@ -1277,3 +1279,133 @@ describe('createComponentConfig', () => {
});
});
});
describe('getCommandOptions', () => {
it('returns null when commandOptionsExpression is null', () => {
const result = getCommandOptions(null);
expect(result).toBeNull();
});
it('parses and returns command options correctly', () => {
const commandOptionsExpression = {
properties: [
{
range: [],
loc: {},
type: '',
key: {
name: 'hotspotUpdate',
loc: {},
},
value: {
elements: [
{
value: 'value',
},
],
},
},
],
};
const result = getCommandOptions(commandOptionsExpression);
expect(result).toEqual({
hotspotUpdate: ['value'],
});
});
it('should throw an error if command options are not defined correctly', () => {
const commandOptionsExpression = {
properties: null,
};
expect(() => getCommandOptions(commandOptionsExpression)).toThrowError(
'Failed to parse command options, please check that they are defined correctly',
);
});
});
describe('getOptions', () => {
it('returns null if optionsExpression is falsy', () => {
expect(getOptions(null)).toBeNull();
expect(getOptions(undefined)).toBeNull();
expect(getOptions(false)).toBeNull();
expect(getOptions(0)).toBeNull();
expect(getOptions('')).toBeNull();
});
it('parses and returns options correctly if codegen options are defined correctly', () => {
const optionsExpression = {
properties: [
{
value: {
type: 'ArrayExpression',
value: 'value',
elements: [
{
value: 'value1',
},
],
},
key: {
name: 'keyName',
},
},
],
};
expect(getOptions(optionsExpression)).toEqual({
keyName: ['value1'],
});
});
it('throws an error if codegen options are not defined correctly', () => {
const optionsExpression = {
properties: null,
};
expect(() => getOptions(optionsExpression)).toThrowError(
'Failed to parse codegen options, please check that they are defined correctly',
);
});
it('throws an error if both paperComponentName and paperComponentNameDeprecated are used', () => {
const optionsExpression = {
properties: [
{
key: {name: 'paperComponentName'},
value: {value: 'RCTRefreshControl'},
},
{
key: {name: 'paperComponentNameDeprecated'},
value: {value: 'RCTSwitch'},
},
],
};
expect(() => getOptions(optionsExpression)).toThrowError(
'Failed to parse codegen options, cannot use both paperComponentName and paperComponentNameDeprecated',
);
});
it('returns options if only paperComponentName is used', () => {
const optionsExpression = {
properties: [
{
key: {name: 'paperComponentName'},
value: {value: 'RCTRefreshControl'},
},
],
};
const expectedOptions = {paperComponentName: 'RCTRefreshControl'};
expect(getOptions(optionsExpression)).toEqual(expectedOptions);
});
it('returns options if only paperComponentNameDeprecated is used', () => {
const optionsExpression = {
properties: [
{
key: {name: 'paperComponentNameDeprecated'},
value: {value: 'RCTRefreshControl'},
},
],
};
const expectedOptions = {paperComponentNameDeprecated: 'RCTRefreshControl'};
expect(getOptions(optionsExpression)).toEqual(expectedOptions);
});
});
@@ -11,19 +11,20 @@
'use strict';
import type {Parser} from '../../parser';
import type {TypeDeclarationMap} from '../../utils';
import type {CommandOptions} from './options';
import type {CommandOptions} from '../../parsers-commons';
import type {ComponentSchemaBuilderConfig} from '../../schema.js';
const {getCommands} = require('./commands');
const {getEvents} = require('./events');
const {getExtendsProps, removeKnownExtends} = require('./extends');
const {getCommandOptions, getOptions} = require('./options');
const {getProps} = require('./props');
const {getProperties} = require('./componentsUtils.js');
const {throwIfMoreThanOneCodegenNativecommands} = require('../../error-utils');
const {
createComponentConfig,
findNativeComponentType,
getCommandOptions,
getOptions,
} = require('../../parsers-commons');
// $FlowFixMe[signature-verification-failure] there's no flowtype for AST
@@ -1,87 +0,0 @@
/**
* 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
* @format
*/
'use strict';
import type {OptionsShape} from '../../../CodegenSchema.js';
// $FlowFixMe[unclear-type] there's no flowtype for ASTs
type OptionsAST = Object;
export type CommandOptions = $ReadOnly<{
supportedCommands: $ReadOnlyArray<string>,
}>;
function getCommandOptions(
commandOptionsExpression: OptionsAST,
): ?CommandOptions {
if (commandOptionsExpression == null) {
return null;
}
let foundOptions;
try {
foundOptions = commandOptionsExpression.properties.reduce(
(options, prop) => {
options[prop.key.name] = (
(prop && prop.value && prop.value.elements) ||
[]
).map(element => element && element.value);
return options;
},
{},
);
} catch (e) {
throw new Error(
'Failed to parse command options, please check that they are defined correctly',
);
}
return foundOptions;
}
function getOptions(optionsExpression: OptionsAST): ?OptionsShape {
if (!optionsExpression) {
return null;
}
let foundOptions;
try {
foundOptions = optionsExpression.properties.reduce((options, prop) => {
if (prop.value.type === 'ArrayExpression') {
options[prop.key.name] = prop.value.elements.map(
element => element.value,
);
} else {
options[prop.key.name] = prop.value.value;
}
return options;
}, {});
} catch (e) {
throw new Error(
'Failed to parse codegen options, please check that they are defined correctly',
);
}
if (
foundOptions.paperComponentName &&
foundOptions.paperComponentNameDeprecated
) {
throw new Error(
'Failed to parse codegen options, cannot use both paperComponentName and paperComponentNameDeprecated',
);
}
return foundOptions;
}
module.exports = {
getCommandOptions,
getOptions,
};
@@ -22,6 +22,7 @@ import type {
NativeModulePropertyShape,
SchemaType,
NativeModuleEnumMap,
OptionsShape,
} from '../CodegenSchema.js';
import type {Parser} from './parser';
@@ -61,6 +62,13 @@ const {
const invariant = require('invariant');
export type CommandOptions = $ReadOnly<{
supportedCommands: $ReadOnlyArray<string>,
}>;
// $FlowFixMe[unclear-type] TODO(T108222691): Use flow-types for @babel/parser
type OptionsAST = Object;
function wrapModuleSchema(
nativeModuleSchema: NativeModuleSchema,
hasteModuleName: string,
@@ -699,6 +707,68 @@ function findNativeComponentType(
}
}
function getCommandOptions(
commandOptionsExpression: OptionsAST,
): ?CommandOptions {
if (commandOptionsExpression == null) {
return null;
}
let foundOptions;
try {
foundOptions = commandOptionsExpression.properties.reduce(
(options, prop) => {
options[prop.key.name] = (
(prop && prop.value && prop.value.elements) ||
[]
).map(element => element && element.value);
return options;
},
{},
);
} catch (e) {
throw new Error(
'Failed to parse command options, please check that they are defined correctly',
);
}
return foundOptions;
}
function getOptions(optionsExpression: OptionsAST): ?OptionsShape {
if (!optionsExpression) {
return null;
}
let foundOptions;
try {
foundOptions = optionsExpression.properties.reduce((options, prop) => {
if (prop.value.type === 'ArrayExpression') {
options[prop.key.name] = prop.value.elements.map(
element => element.value,
);
} else {
options[prop.key.name] = prop.value.value;
}
return options;
}, {});
} catch (e) {
throw new Error(
'Failed to parse codegen options, please check that they are defined correctly',
);
}
if (
foundOptions.paperComponentName &&
foundOptions.paperComponentNameDeprecated
) {
throw new Error(
'Failed to parse codegen options, cannot use both paperComponentName and paperComponentNameDeprecated',
);
}
return foundOptions;
}
module.exports = {
wrapModuleSchema,
unwrapNullable,
@@ -714,4 +784,6 @@ module.exports = {
parseModuleName,
buildModuleSchema,
findNativeComponentType,
getCommandOptions,
getOptions,
};
@@ -12,19 +12,20 @@
import type {ExtendsPropsShape} from '../../../CodegenSchema.js';
import type {Parser} from '../../parser';
import type {TypeDeclarationMap} from '../../utils';
import type {CommandOptions} from './options';
import type {CommandOptions} from '../../parsers-commons';
import type {ComponentSchemaBuilderConfig} from '../../schema.js';
const {getCommands} = require('./commands');
const {getEvents} = require('./events');
const {categorizeProps} = require('./extends');
const {getCommandOptions, getOptions} = require('./options');
const {getProps} = require('./props');
const {getProperties} = require('./componentsUtils.js');
const {throwIfMoreThanOneCodegenNativecommands} = require('../../error-utils');
const {
createComponentConfig,
findNativeComponentType,
getCommandOptions,
getOptions,
} = require('../../parsers-commons');
// $FlowFixMe[signature-verification-failure] TODO(T108222691): Use flow-types for @babel/parser
@@ -1,87 +0,0 @@
/**
* 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
* @format
*/
'use strict';
import type {OptionsShape} from '../../../CodegenSchema.js';
// $FlowFixMe[unclear-type] TODO(T108222691): Use flow-types for @babel/parser
type OptionsAST = Object;
export type CommandOptions = $ReadOnly<{
supportedCommands: $ReadOnlyArray<string>,
}>;
function getCommandOptions(
commandOptionsExpression: OptionsAST,
): ?CommandOptions {
if (commandOptionsExpression == null) {
return null;
}
let foundOptions;
try {
foundOptions = commandOptionsExpression.properties.reduce(
(options, prop) => {
options[prop.key.name] = (
(prop && prop.value && prop.value.elements) ||
[]
).map(element => element && element.value);
return options;
},
{},
);
} catch (e) {
throw new Error(
'Failed to parse command options, please check that they are defined correctly',
);
}
return foundOptions;
}
function getOptions(optionsExpression: OptionsAST): ?OptionsShape {
if (!optionsExpression) {
return null;
}
let foundOptions;
try {
foundOptions = optionsExpression.properties.reduce((options, prop) => {
if (prop.value.type === 'ArrayExpression') {
options[prop.key.name] = prop.value.elements.map(
element => element.value,
);
} else {
options[prop.key.name] = prop.value.value;
}
return options;
}, {});
} catch (e) {
throw new Error(
'Failed to parse codegen options, please check that they are defined correctly',
);
}
if (
foundOptions.paperComponentName &&
foundOptions.paperComponentNameDeprecated
) {
throw new Error(
'Failed to parse codegen options, cannot use both paperComponentName and paperComponentNameDeprecated',
);
}
return foundOptions;
}
module.exports = {
getCommandOptions,
getOptions,
};