Skip to content

Commit 969a8d0

Browse files
kyawthura-ggfacebook-github-bot
authored andcommitted
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: #36500 Test Plan: `yarn test react-native-codegen` Reviewed By: cortinico Differential Revision: D44415265 Pulled By: cipolleschi fbshipit-source-id: ed13b553a6f782beb0f1aec79bd17d865a96fac9
1 parent 3ac7a5e commit 969a8d0

File tree

8 files changed

+82
-59
lines changed

8 files changed

+82
-59
lines changed

packages/react-native-codegen/src/parsers/__tests__/parsers-commons-test.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
buildSchema,
2222
parseModuleName,
2323
createComponentConfig,
24+
propertyNames,
2425
getCommandOptions,
2526
getOptions,
2627
getCommandTypeNameAndOptionsExpression,
@@ -1536,4 +1537,23 @@ describe('getCommandTypeNameAndOptionsExpression', () => {
15361537
commandOptionsExpression,
15371538
});
15381539
});
1540+
1541+
describe('propertyNames', () => {
1542+
it('returns propertyNames with valid properties', () => {
1543+
const properties = [
1544+
{key: {name: 'testName'}},
1545+
{key: {name: 'testName2'}},
1546+
];
1547+
const expected = ['testName', 'testName2'];
1548+
expect(propertyNames(properties)).toEqual(expected);
1549+
});
1550+
1551+
it('returns empty propertyNames with incorrect properties', () => {
1552+
const properties = [
1553+
{key: {invalid: 'testName'}},
1554+
{key: {invalid: 'testName2'}},
1555+
];
1556+
expect(propertyNames(properties)).toEqual([]);
1557+
});
1558+
});
15391559
});

packages/react-native-codegen/src/parsers/flow/components/index.js

Lines changed: 18 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010

1111
'use strict';
1212
import type {Parser} from '../../parser';
13-
import type {TypeDeclarationMap} from '../../utils';
14-
import type {CommandOptions} from '../../parsers-commons';
1513
import type {ComponentSchemaBuilderConfig} from '../../schema.js';
1614

1715
const {getCommands} = require('./commands');
@@ -23,6 +21,7 @@ const {throwIfMoreThanOneCodegenNativecommands} = require('../../error-utils');
2321
const {
2422
createComponentConfig,
2523
findNativeComponentType,
24+
propertyNames,
2625
getCommandOptions,
2726
getOptions,
2827
getCommandTypeNameAndOptionsExpression,
@@ -62,16 +61,16 @@ function findComponentConfig(ast: $FlowFixMe, parser: Parser) {
6261
return createComponentConfig(foundConfig, commandsTypeNames);
6362
}
6463

65-
function getCommandProperties(
66-
/* $FlowFixMe[missing-local-annot] The type annotation(s) required by Flow's
67-
* LTI update could not be added via codemod */
68-
commandTypeName,
69-
types: TypeDeclarationMap,
70-
commandOptions: ?CommandOptions,
71-
) {
64+
function getCommandProperties(ast: $FlowFixMe, parser: Parser) {
65+
const {commandTypeName, commandOptionsExpression} = findComponentConfig(
66+
ast,
67+
parser,
68+
);
69+
7270
if (commandTypeName == null) {
7371
return [];
7472
}
73+
const types = parser.getTypes(ast);
7574

7675
const typeAlias = types[commandTypeName];
7776

@@ -81,18 +80,16 @@ function getCommandProperties(
8180
);
8281
}
8382

84-
let properties;
85-
try {
86-
properties = typeAlias.body.properties;
87-
} catch (e) {
83+
const properties = parser.bodyProperties(typeAlias);
84+
if (!properties) {
8885
throw new Error(
8986
`Failed to find type definition for "${commandTypeName}", please check that you have a valid codegen flow file`,
9087
);
9188
}
9289

93-
const flowPropertyNames = properties
94-
.map(property => property && property.key && property.key.name)
95-
.filter(Boolean);
90+
const flowPropertyNames = propertyNames(properties);
91+
92+
const commandOptions = getCommandOptions(commandOptionsExpression);
9693

9794
if (commandOptions == null || commandOptions.supportedCommands == null) {
9895
throw new Error(
@@ -121,24 +118,16 @@ function buildComponentSchema(
121118
ast: $FlowFixMe,
122119
parser: Parser,
123120
): ComponentSchemaBuilderConfig {
124-
const {
125-
componentName,
126-
propsTypeName,
127-
commandTypeName,
128-
commandOptionsExpression,
129-
optionsExpression,
130-
} = findComponentConfig(ast, parser);
121+
const {componentName, propsTypeName, optionsExpression} = findComponentConfig(
122+
ast,
123+
parser,
124+
);
131125

132126
const types = parser.getTypes(ast);
133127

134128
const propProperties = getProperties(propsTypeName, types);
135-
const commandOptions = getCommandOptions(commandOptionsExpression);
136129

137-
const commandProperties = getCommandProperties(
138-
commandTypeName,
139-
types,
140-
commandOptions,
141-
);
130+
const commandProperties = getCommandProperties(ast, parser);
142131

143132
const extendsProps = getExtendsProps(propProperties, types);
144133
const options = getOptions(optionsExpression);

packages/react-native-codegen/src/parsers/flow/parser.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,10 @@ class FlowParser implements Parser {
321321
getAnnotatedElementProperties(annotatedElement: $FlowFixMe): $FlowFixMe {
322322
return annotatedElement.right.properties;
323323
}
324+
325+
bodyProperties(typeAlias: $FlowFixMe): $ReadOnlyArray<$FlowFixMe> {
326+
return typeAlias.body.properties;
327+
}
324328
}
325329

326330
module.exports = {

packages/react-native-codegen/src/parsers/parser.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,4 +241,11 @@ export interface Parser {
241241
* @returns: the properties of annotated element.
242242
*/
243243
getAnnotatedElementProperties(annotatedElement: $FlowFixMe): $FlowFixMe;
244+
245+
/**
246+
* Given a typeAlias, it returns an array of properties.
247+
* @parameter typeAlias: the type alias.
248+
* @returns: an array of properties.
249+
*/
250+
bodyProperties(typeAlias: $FlowFixMe): $ReadOnlyArray<$FlowFixMe>;
244251
}

packages/react-native-codegen/src/parsers/parserMock.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,4 +235,8 @@ export class MockedParser implements Parser {
235235
getAnnotatedElementProperties(annotatedElement: $FlowFixMe): $FlowFixMe {
236236
return annotatedElement.right.properties;
237237
}
238+
239+
bodyProperties(typeAlias: $FlowFixMe): $ReadOnlyArray<$FlowFixMe> {
240+
return typeAlias.body.properties;
241+
}
238242
}

packages/react-native-codegen/src/parsers/parsers-commons.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -765,7 +765,6 @@ function getOptions(optionsExpression: OptionsAST): ?OptionsShape {
765765
'Failed to parse codegen options, cannot use both paperComponentName and paperComponentNameDeprecated',
766766
);
767767
}
768-
769768
return foundOptions;
770769
}
771770

@@ -810,6 +809,14 @@ function getCommandTypeNameAndOptionsExpression(
810809
};
811810
}
812811

812+
function propertyNames(
813+
properties: $ReadOnlyArray<$FlowFixMe>,
814+
): $ReadOnlyArray<$FlowFixMe> {
815+
return properties
816+
.map(property => property && property.key && property.key.name)
817+
.filter(Boolean);
818+
}
819+
813820
module.exports = {
814821
wrapModuleSchema,
815822
unwrapNullable,
@@ -825,6 +832,7 @@ module.exports = {
825832
parseModuleName,
826833
buildModuleSchema,
827834
findNativeComponentType,
835+
propertyNames,
828836
getCommandOptions,
829837
getOptions,
830838
getCommandTypeNameAndOptionsExpression,

packages/react-native-codegen/src/parsers/typescript/components/index.js

Lines changed: 16 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111
'use strict';
1212
import type {ExtendsPropsShape} from '../../../CodegenSchema.js';
1313
import type {Parser} from '../../parser';
14-
import type {TypeDeclarationMap} from '../../utils';
15-
import type {CommandOptions} from '../../parsers-commons';
1614
import type {ComponentSchemaBuilderConfig} from '../../schema.js';
1715

1816
const {getCommands} = require('./commands');
@@ -24,6 +22,7 @@ const {throwIfMoreThanOneCodegenNativecommands} = require('../../error-utils');
2422
const {
2523
createComponentConfig,
2624
findNativeComponentType,
25+
propertyNames,
2726
getCommandOptions,
2827
getOptions,
2928
getCommandTypeNameAndOptionsExpression,
@@ -63,17 +62,16 @@ function findComponentConfig(ast: $FlowFixMe, parser: Parser) {
6362
return createComponentConfig(foundConfig, commandsTypeNames);
6463
}
6564

66-
function getCommandProperties(
67-
/* $FlowFixMe[missing-local-annot] The type annotation(s) required by Flow's
68-
* LTI update could not be added via codemod */
69-
commandTypeName,
70-
types: TypeDeclarationMap,
71-
commandOptions: ?CommandOptions,
72-
) {
65+
function getCommandProperties(ast: $FlowFixMe, parser: Parser) {
66+
const {commandTypeName, commandOptionsExpression} = findComponentConfig(
67+
ast,
68+
parser,
69+
);
7370
if (commandTypeName == null) {
7471
return [];
7572
}
7673

74+
const types = parser.getTypes(ast);
7775
const typeAlias = types[commandTypeName];
7876

7977
if (typeAlias.type !== 'TSInterfaceDeclaration') {
@@ -82,19 +80,16 @@ function getCommandProperties(
8280
);
8381
}
8482

85-
let properties;
86-
try {
87-
properties = typeAlias.body.body;
88-
} catch (e) {
83+
const properties = parser.bodyProperties(typeAlias);
84+
if (!properties) {
8985
throw new Error(
9086
`Failed to find type definition for "${commandTypeName}", please check that you have a valid codegen typescript file`,
9187
);
9288
}
9389

94-
const typeScriptPropertyNames = properties
95-
.map(property => property && property.key && property.key.name)
96-
.filter(Boolean);
90+
const typeScriptPropertyNames = propertyNames(properties);
9791

92+
const commandOptions = getCommandOptions(commandOptionsExpression);
9893
if (commandOptions == null || commandOptions.supportedCommands == null) {
9994
throw new Error(
10095
'codegenNativeCommands must be given an options object with supportedCommands array',
@@ -126,24 +121,16 @@ function buildComponentSchema(
126121
ast: $FlowFixMe,
127122
parser: Parser,
128123
): ComponentSchemaBuilderConfig {
129-
const {
130-
componentName,
131-
propsTypeName,
132-
commandTypeName,
133-
commandOptionsExpression,
134-
optionsExpression,
135-
} = findComponentConfig(ast, parser);
124+
const {componentName, propsTypeName, optionsExpression} = findComponentConfig(
125+
ast,
126+
parser,
127+
);
136128

137129
const types = parser.getTypes(ast);
138130

139131
const propProperties = getProperties(propsTypeName, types);
140-
const commandOptions = getCommandOptions(commandOptionsExpression);
141132

142-
const commandProperties = getCommandProperties(
143-
commandTypeName,
144-
types,
145-
commandOptions,
146-
);
133+
const commandProperties = getCommandProperties(ast, parser);
147134

148135
const options = getOptions(optionsExpression);
149136

packages/react-native-codegen/src/parsers/typescript/parser.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,10 @@ class TypeScriptParser implements Parser {
307307
getAnnotatedElementProperties(annotatedElement: $FlowFixMe): $FlowFixMe {
308308
return annotatedElement.typeAnnotation.members;
309309
}
310+
311+
bodyProperties(typeAlias: TypeDeclarationMap): $ReadOnlyArray<$FlowFixMe> {
312+
return typeAlias.body.body;
313+
}
310314
}
311315

312316
module.exports = {

0 commit comments

Comments
 (0)