mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Enrich getCommandProperties with the parser object (#36500)
Summary: > [Codegen 101] The code of getCommandProperties is almost identical in [Flow](https://github.com/facebook/react-native/blob/main/packages/react-native-codegen/src/parsers/flow/components/index.js#L128) and [TS](https://github.com/facebook/react-native/blob/main/packages/react-native-codegen/src/parsers/typescript/components/index.js#L129). There are small differences between flow/ts, so we need for it to accept a Parser object. Enrich the parser object with the required methods if necessary. ## Changelog: [Internal] [Changed] - Enrich getCommandProperties with the parser object Pull Request resolved: https://github.com/facebook/react-native/pull/36500 Test Plan: `yarn test react-native-codegen` Reviewed By: cortinico Differential Revision: D44415265 Pulled By: cipolleschi fbshipit-source-id: ed13b553a6f782beb0f1aec79bd17d865a96fac9
This commit is contained in:
committed by
Facebook GitHub Bot
parent
3ac7a5ef4e
commit
969a8d0799
@@ -21,6 +21,7 @@ import {
|
||||
buildSchema,
|
||||
parseModuleName,
|
||||
createComponentConfig,
|
||||
propertyNames,
|
||||
getCommandOptions,
|
||||
getOptions,
|
||||
getCommandTypeNameAndOptionsExpression,
|
||||
@@ -1536,4 +1537,23 @@ describe('getCommandTypeNameAndOptionsExpression', () => {
|
||||
commandOptionsExpression,
|
||||
});
|
||||
});
|
||||
|
||||
describe('propertyNames', () => {
|
||||
it('returns propertyNames with valid properties', () => {
|
||||
const properties = [
|
||||
{key: {name: 'testName'}},
|
||||
{key: {name: 'testName2'}},
|
||||
];
|
||||
const expected = ['testName', 'testName2'];
|
||||
expect(propertyNames(properties)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('returns empty propertyNames with incorrect properties', () => {
|
||||
const properties = [
|
||||
{key: {invalid: 'testName'}},
|
||||
{key: {invalid: 'testName2'}},
|
||||
];
|
||||
expect(propertyNames(properties)).toEqual([]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
|
||||
'use strict';
|
||||
import type {Parser} from '../../parser';
|
||||
import type {TypeDeclarationMap} from '../../utils';
|
||||
import type {CommandOptions} from '../../parsers-commons';
|
||||
import type {ComponentSchemaBuilderConfig} from '../../schema.js';
|
||||
|
||||
const {getCommands} = require('./commands');
|
||||
@@ -23,6 +21,7 @@ const {throwIfMoreThanOneCodegenNativecommands} = require('../../error-utils');
|
||||
const {
|
||||
createComponentConfig,
|
||||
findNativeComponentType,
|
||||
propertyNames,
|
||||
getCommandOptions,
|
||||
getOptions,
|
||||
getCommandTypeNameAndOptionsExpression,
|
||||
@@ -62,16 +61,16 @@ function findComponentConfig(ast: $FlowFixMe, parser: Parser) {
|
||||
return createComponentConfig(foundConfig, commandsTypeNames);
|
||||
}
|
||||
|
||||
function getCommandProperties(
|
||||
/* $FlowFixMe[missing-local-annot] The type annotation(s) required by Flow's
|
||||
* LTI update could not be added via codemod */
|
||||
commandTypeName,
|
||||
types: TypeDeclarationMap,
|
||||
commandOptions: ?CommandOptions,
|
||||
) {
|
||||
function getCommandProperties(ast: $FlowFixMe, parser: Parser) {
|
||||
const {commandTypeName, commandOptionsExpression} = findComponentConfig(
|
||||
ast,
|
||||
parser,
|
||||
);
|
||||
|
||||
if (commandTypeName == null) {
|
||||
return [];
|
||||
}
|
||||
const types = parser.getTypes(ast);
|
||||
|
||||
const typeAlias = types[commandTypeName];
|
||||
|
||||
@@ -81,18 +80,16 @@ function getCommandProperties(
|
||||
);
|
||||
}
|
||||
|
||||
let properties;
|
||||
try {
|
||||
properties = typeAlias.body.properties;
|
||||
} catch (e) {
|
||||
const properties = parser.bodyProperties(typeAlias);
|
||||
if (!properties) {
|
||||
throw new Error(
|
||||
`Failed to find type definition for "${commandTypeName}", please check that you have a valid codegen flow file`,
|
||||
);
|
||||
}
|
||||
|
||||
const flowPropertyNames = properties
|
||||
.map(property => property && property.key && property.key.name)
|
||||
.filter(Boolean);
|
||||
const flowPropertyNames = propertyNames(properties);
|
||||
|
||||
const commandOptions = getCommandOptions(commandOptionsExpression);
|
||||
|
||||
if (commandOptions == null || commandOptions.supportedCommands == null) {
|
||||
throw new Error(
|
||||
@@ -121,24 +118,16 @@ function buildComponentSchema(
|
||||
ast: $FlowFixMe,
|
||||
parser: Parser,
|
||||
): ComponentSchemaBuilderConfig {
|
||||
const {
|
||||
componentName,
|
||||
propsTypeName,
|
||||
commandTypeName,
|
||||
commandOptionsExpression,
|
||||
optionsExpression,
|
||||
} = findComponentConfig(ast, parser);
|
||||
const {componentName, propsTypeName, optionsExpression} = findComponentConfig(
|
||||
ast,
|
||||
parser,
|
||||
);
|
||||
|
||||
const types = parser.getTypes(ast);
|
||||
|
||||
const propProperties = getProperties(propsTypeName, types);
|
||||
const commandOptions = getCommandOptions(commandOptionsExpression);
|
||||
|
||||
const commandProperties = getCommandProperties(
|
||||
commandTypeName,
|
||||
types,
|
||||
commandOptions,
|
||||
);
|
||||
const commandProperties = getCommandProperties(ast, parser);
|
||||
|
||||
const extendsProps = getExtendsProps(propProperties, types);
|
||||
const options = getOptions(optionsExpression);
|
||||
|
||||
@@ -321,6 +321,10 @@ class FlowParser implements Parser {
|
||||
getAnnotatedElementProperties(annotatedElement: $FlowFixMe): $FlowFixMe {
|
||||
return annotatedElement.right.properties;
|
||||
}
|
||||
|
||||
bodyProperties(typeAlias: $FlowFixMe): $ReadOnlyArray<$FlowFixMe> {
|
||||
return typeAlias.body.properties;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
||||
@@ -241,4 +241,11 @@ export interface Parser {
|
||||
* @returns: the properties of annotated element.
|
||||
*/
|
||||
getAnnotatedElementProperties(annotatedElement: $FlowFixMe): $FlowFixMe;
|
||||
|
||||
/**
|
||||
* Given a typeAlias, it returns an array of properties.
|
||||
* @parameter typeAlias: the type alias.
|
||||
* @returns: an array of properties.
|
||||
*/
|
||||
bodyProperties(typeAlias: $FlowFixMe): $ReadOnlyArray<$FlowFixMe>;
|
||||
}
|
||||
|
||||
@@ -235,4 +235,8 @@ export class MockedParser implements Parser {
|
||||
getAnnotatedElementProperties(annotatedElement: $FlowFixMe): $FlowFixMe {
|
||||
return annotatedElement.right.properties;
|
||||
}
|
||||
|
||||
bodyProperties(typeAlias: $FlowFixMe): $ReadOnlyArray<$FlowFixMe> {
|
||||
return typeAlias.body.properties;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -765,7 +765,6 @@ function getOptions(optionsExpression: OptionsAST): ?OptionsShape {
|
||||
'Failed to parse codegen options, cannot use both paperComponentName and paperComponentNameDeprecated',
|
||||
);
|
||||
}
|
||||
|
||||
return foundOptions;
|
||||
}
|
||||
|
||||
@@ -810,6 +809,14 @@ function getCommandTypeNameAndOptionsExpression(
|
||||
};
|
||||
}
|
||||
|
||||
function propertyNames(
|
||||
properties: $ReadOnlyArray<$FlowFixMe>,
|
||||
): $ReadOnlyArray<$FlowFixMe> {
|
||||
return properties
|
||||
.map(property => property && property.key && property.key.name)
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
wrapModuleSchema,
|
||||
unwrapNullable,
|
||||
@@ -825,6 +832,7 @@ module.exports = {
|
||||
parseModuleName,
|
||||
buildModuleSchema,
|
||||
findNativeComponentType,
|
||||
propertyNames,
|
||||
getCommandOptions,
|
||||
getOptions,
|
||||
getCommandTypeNameAndOptionsExpression,
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
'use strict';
|
||||
import type {ExtendsPropsShape} from '../../../CodegenSchema.js';
|
||||
import type {Parser} from '../../parser';
|
||||
import type {TypeDeclarationMap} from '../../utils';
|
||||
import type {CommandOptions} from '../../parsers-commons';
|
||||
import type {ComponentSchemaBuilderConfig} from '../../schema.js';
|
||||
|
||||
const {getCommands} = require('./commands');
|
||||
@@ -24,6 +22,7 @@ const {throwIfMoreThanOneCodegenNativecommands} = require('../../error-utils');
|
||||
const {
|
||||
createComponentConfig,
|
||||
findNativeComponentType,
|
||||
propertyNames,
|
||||
getCommandOptions,
|
||||
getOptions,
|
||||
getCommandTypeNameAndOptionsExpression,
|
||||
@@ -63,17 +62,16 @@ function findComponentConfig(ast: $FlowFixMe, parser: Parser) {
|
||||
return createComponentConfig(foundConfig, commandsTypeNames);
|
||||
}
|
||||
|
||||
function getCommandProperties(
|
||||
/* $FlowFixMe[missing-local-annot] The type annotation(s) required by Flow's
|
||||
* LTI update could not be added via codemod */
|
||||
commandTypeName,
|
||||
types: TypeDeclarationMap,
|
||||
commandOptions: ?CommandOptions,
|
||||
) {
|
||||
function getCommandProperties(ast: $FlowFixMe, parser: Parser) {
|
||||
const {commandTypeName, commandOptionsExpression} = findComponentConfig(
|
||||
ast,
|
||||
parser,
|
||||
);
|
||||
if (commandTypeName == null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const types = parser.getTypes(ast);
|
||||
const typeAlias = types[commandTypeName];
|
||||
|
||||
if (typeAlias.type !== 'TSInterfaceDeclaration') {
|
||||
@@ -82,19 +80,16 @@ function getCommandProperties(
|
||||
);
|
||||
}
|
||||
|
||||
let properties;
|
||||
try {
|
||||
properties = typeAlias.body.body;
|
||||
} catch (e) {
|
||||
const properties = parser.bodyProperties(typeAlias);
|
||||
if (!properties) {
|
||||
throw new Error(
|
||||
`Failed to find type definition for "${commandTypeName}", please check that you have a valid codegen typescript file`,
|
||||
);
|
||||
}
|
||||
|
||||
const typeScriptPropertyNames = properties
|
||||
.map(property => property && property.key && property.key.name)
|
||||
.filter(Boolean);
|
||||
const typeScriptPropertyNames = propertyNames(properties);
|
||||
|
||||
const commandOptions = getCommandOptions(commandOptionsExpression);
|
||||
if (commandOptions == null || commandOptions.supportedCommands == null) {
|
||||
throw new Error(
|
||||
'codegenNativeCommands must be given an options object with supportedCommands array',
|
||||
@@ -126,24 +121,16 @@ function buildComponentSchema(
|
||||
ast: $FlowFixMe,
|
||||
parser: Parser,
|
||||
): ComponentSchemaBuilderConfig {
|
||||
const {
|
||||
componentName,
|
||||
propsTypeName,
|
||||
commandTypeName,
|
||||
commandOptionsExpression,
|
||||
optionsExpression,
|
||||
} = findComponentConfig(ast, parser);
|
||||
const {componentName, propsTypeName, optionsExpression} = findComponentConfig(
|
||||
ast,
|
||||
parser,
|
||||
);
|
||||
|
||||
const types = parser.getTypes(ast);
|
||||
|
||||
const propProperties = getProperties(propsTypeName, types);
|
||||
const commandOptions = getCommandOptions(commandOptionsExpression);
|
||||
|
||||
const commandProperties = getCommandProperties(
|
||||
commandTypeName,
|
||||
types,
|
||||
commandOptions,
|
||||
);
|
||||
const commandProperties = getCommandProperties(ast, parser);
|
||||
|
||||
const options = getOptions(optionsExpression);
|
||||
|
||||
|
||||
@@ -307,6 +307,10 @@ class TypeScriptParser implements Parser {
|
||||
getAnnotatedElementProperties(annotatedElement: $FlowFixMe): $FlowFixMe {
|
||||
return annotatedElement.typeAnnotation.members;
|
||||
}
|
||||
|
||||
bodyProperties(typeAlias: TypeDeclarationMap): $ReadOnlyArray<$FlowFixMe> {
|
||||
return typeAlias.body.body;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
||||
Reference in New Issue
Block a user