Add `getProperties` to Parsers and update usages (#37633)
Summary: [Codegen 138] This PR introduces `getProperties` to Parser base class and implements the function in Typescript and Flow Parsers. This PR also gets rid of `getProperties` from : - `packages/react-native-codegen/src/parsers/typescript/components/componentsUtils.js` - `packages/react-native-codegen/src/parsers/flow/components/componentsUtils.js` and updates the usages with `getProperties` from the respective parser objects as requested on https://github.com/facebook/react-native/issues/34872 ## Changelog: [Internal] [Changed] - Add getProperties to Parsers base class and update usages. Pull Request resolved: https://github.com/facebook/react-native/pull/37633 Test Plan: Run yarn jest react-native-codegen and ensure CI is green ## Screenshot of tests passing locally: ![Screenshot 2023-05-31 at 4 38 41 PM](https://github.com/facebook/react-native/assets/64726664/dd660369-eabd-4c2e-a440-a41ed6f9d47a) Reviewed By: cipolleschi Differential Revision: D46322882 Pulled By: rshest fbshipit-source-id: 5506ce5ff395946ea8c1258b152716fea0142b95
This commit is contained in:
Родитель
9c11b81630
Коммит
e73c00f576
|
@ -10,25 +10,10 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
import type {NamedShape} from '../../../CodegenSchema.js';
|
||||
const {getValueFromTypes} = require('../utils.js');
|
||||
import type {TypeDeclarationMap, PropAST, ASTNode} from '../../utils';
|
||||
import type {BuildSchemaFN, Parser} from '../../parser';
|
||||
|
||||
function getProperties(
|
||||
typeName: string,
|
||||
types: TypeDeclarationMap,
|
||||
): $FlowFixMe {
|
||||
const typeAlias = types[typeName];
|
||||
try {
|
||||
return typeAlias.right.typeParameters.params[0].properties;
|
||||
} catch (e) {
|
||||
throw new Error(
|
||||
`Failed to find type definition for "${typeName}", please check that you have a valid codegen flow file`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function getTypeAnnotationForArray<+T>(
|
||||
name: string,
|
||||
typeAnnotation: $FlowFixMe,
|
||||
|
@ -63,6 +48,7 @@ function getTypeAnnotationForArray<+T>(
|
|||
properties: flattenProperties(
|
||||
objectType.typeParameters.params[0].properties,
|
||||
types,
|
||||
parser,
|
||||
)
|
||||
.map(prop => buildSchema(prop, types, parser))
|
||||
.filter(Boolean),
|
||||
|
@ -84,6 +70,7 @@ function getTypeAnnotationForArray<+T>(
|
|||
properties: flattenProperties(
|
||||
nestedObjectType.typeParameters.params[0].properties,
|
||||
types,
|
||||
parser,
|
||||
)
|
||||
.map(prop => buildSchema(prop, types, parser))
|
||||
.filter(Boolean),
|
||||
|
@ -190,6 +177,7 @@ function getTypeAnnotationForArray<+T>(
|
|||
function flattenProperties(
|
||||
typeDefinition: $ReadOnlyArray<PropAST>,
|
||||
types: TypeDeclarationMap,
|
||||
parser: Parser,
|
||||
): $ReadOnlyArray<PropAST> {
|
||||
return typeDefinition
|
||||
.map(property => {
|
||||
|
@ -197,8 +185,9 @@ function flattenProperties(
|
|||
return property;
|
||||
} else if (property.type === 'ObjectTypeSpreadProperty') {
|
||||
return flattenProperties(
|
||||
getProperties(property.argument.id.name, types),
|
||||
parser.getProperties(property.argument.id.name, types),
|
||||
types,
|
||||
parser,
|
||||
);
|
||||
}
|
||||
})
|
||||
|
@ -265,6 +254,7 @@ function getTypeAnnotation<+T>(
|
|||
properties: flattenProperties(
|
||||
typeAnnotation.typeParameters.params[0].properties,
|
||||
types,
|
||||
parser,
|
||||
)
|
||||
.map(prop => buildSchema(prop, types, parser))
|
||||
.filter(Boolean),
|
||||
|
@ -503,7 +493,6 @@ function getSchemaInfo(
|
|||
}
|
||||
|
||||
module.exports = {
|
||||
getProperties,
|
||||
getSchemaInfo,
|
||||
getTypeAnnotation,
|
||||
flattenProperties,
|
||||
|
|
|
@ -14,7 +14,6 @@ import type {ComponentSchemaBuilderConfig} from '../../schema.js';
|
|||
|
||||
const {getCommands} = require('./commands');
|
||||
const {getEvents} = require('./events');
|
||||
const {getProperties} = require('./componentsUtils.js');
|
||||
const {
|
||||
getOptions,
|
||||
findComponentConfig,
|
||||
|
@ -33,7 +32,7 @@ function buildComponentSchema(
|
|||
|
||||
const types = parser.getTypes(ast);
|
||||
|
||||
const propProperties = getProperties(propsTypeName, types);
|
||||
const propProperties = parser.getProperties(propsTypeName, types);
|
||||
const commandProperties = getCommandProperties(ast, parser);
|
||||
const {extendsProps, props} = parser.getProps(propProperties, types);
|
||||
|
||||
|
|
|
@ -511,7 +511,7 @@ class FlowParser implements Parser {
|
|||
extendsProps: $ReadOnlyArray<ExtendsPropsShape>,
|
||||
} {
|
||||
const nonExtendsProps = this.removeKnownExtends(typeDefinition, types);
|
||||
const props = flattenProperties(nonExtendsProps, types)
|
||||
const props = flattenProperties(nonExtendsProps, types, this)
|
||||
.map(property => buildPropSchema(property, types, this))
|
||||
.filter(Boolean);
|
||||
|
||||
|
@ -520,6 +520,17 @@ class FlowParser implements Parser {
|
|||
extendsProps: this.getExtendsProps(typeDefinition, types),
|
||||
};
|
||||
}
|
||||
|
||||
getProperties(typeName: string, types: TypeDeclarationMap): $FlowFixMe {
|
||||
const typeAlias = types[typeName];
|
||||
try {
|
||||
return typeAlias.right.typeParameters.params[0].properties;
|
||||
} catch (e) {
|
||||
throw new Error(
|
||||
`Failed to find type definition for "${typeName}", please check that you have a valid codegen flow file`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
|
|
@ -376,4 +376,6 @@ export interface Parser {
|
|||
props: $ReadOnlyArray<NamedShape<PropTypeAnnotation>>,
|
||||
extendsProps: $ReadOnlyArray<ExtendsPropsShape>,
|
||||
};
|
||||
|
||||
getProperties(typeName: string, types: TypeDeclarationMap): $FlowFixMe;
|
||||
}
|
||||
|
|
|
@ -436,7 +436,7 @@ export class MockedParser implements Parser {
|
|||
extendsProps: $ReadOnlyArray<ExtendsPropsShape>,
|
||||
} {
|
||||
const nonExtendsProps = this.removeKnownExtends(typeDefinition, types);
|
||||
const props = flattenProperties(nonExtendsProps, types)
|
||||
const props = flattenProperties(nonExtendsProps, types, this)
|
||||
.map(property => buildPropSchema(property, types, this))
|
||||
.filter(Boolean);
|
||||
|
||||
|
@ -445,4 +445,15 @@ export class MockedParser implements Parser {
|
|||
extendsProps: this.getExtendsProps(typeDefinition, types),
|
||||
};
|
||||
}
|
||||
|
||||
getProperties(typeName: string, types: TypeDeclarationMap): $FlowFixMe {
|
||||
const typeAlias = types[typeName];
|
||||
try {
|
||||
return typeAlias.right.typeParameters.params[0].properties;
|
||||
} catch (e) {
|
||||
throw new Error(
|
||||
`Failed to find type definition for "${typeName}", please check that you have a valid codegen flow file`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,36 +16,6 @@ const {
|
|||
import type {TypeDeclarationMap, PropAST, ASTNode} from '../../utils';
|
||||
import type {BuildSchemaFN, Parser} from '../../parser';
|
||||
|
||||
function getProperties(
|
||||
typeName: string,
|
||||
types: TypeDeclarationMap,
|
||||
): $FlowFixMe {
|
||||
const alias = types[typeName];
|
||||
if (!alias) {
|
||||
throw new Error(
|
||||
`Failed to find definition for "${typeName}", please check that you have a valid codegen typescript file`,
|
||||
);
|
||||
}
|
||||
const aliasKind =
|
||||
alias.type === 'TSInterfaceDeclaration' ? 'interface' : 'type';
|
||||
|
||||
try {
|
||||
if (aliasKind === 'interface') {
|
||||
return [...(alias.extends ?? []), ...alias.body.body];
|
||||
}
|
||||
|
||||
return (
|
||||
alias.typeAnnotation.members ||
|
||||
alias.typeAnnotation.typeParameters.params[0].members ||
|
||||
alias.typeAnnotation.typeParameters.params
|
||||
);
|
||||
} catch (e) {
|
||||
throw new Error(
|
||||
`Failed to find ${aliasKind} definition for "${typeName}", please check that you have a valid codegen typescript file`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function getUnionOfLiterals(
|
||||
name: string,
|
||||
forArray: boolean,
|
||||
|
@ -175,7 +145,7 @@ function buildObjectType<T>(
|
|||
parser: Parser,
|
||||
buildSchema: BuildSchemaFN<T>,
|
||||
): $FlowFixMe {
|
||||
const flattenedProperties = flattenProperties(rawProperties, types);
|
||||
const flattenedProperties = flattenProperties(rawProperties, types, parser);
|
||||
const properties = flattenedProperties
|
||||
.map(prop => buildSchema(prop, types, parser))
|
||||
.filter(Boolean);
|
||||
|
@ -497,6 +467,7 @@ function verifyPropNotAlreadyDefined(
|
|||
function flattenProperties(
|
||||
typeDefinition: $ReadOnlyArray<PropAST>,
|
||||
types: TypeDeclarationMap,
|
||||
parser: Parser,
|
||||
): $ReadOnlyArray<PropAST> {
|
||||
return typeDefinition
|
||||
.map(property => {
|
||||
|
@ -504,23 +475,29 @@ function flattenProperties(
|
|||
return property;
|
||||
} else if (property.type === 'TSTypeReference') {
|
||||
return flattenProperties(
|
||||
getProperties(property.typeName.name, types),
|
||||
parser.getProperties(property.typeName.name, types),
|
||||
types,
|
||||
parser,
|
||||
);
|
||||
} else if (
|
||||
property.type === 'TSExpressionWithTypeArguments' ||
|
||||
property.type === 'TSInterfaceHeritage'
|
||||
) {
|
||||
return flattenProperties(
|
||||
getProperties(property.expression.name, types),
|
||||
parser.getProperties(property.expression.name, types),
|
||||
types,
|
||||
parser,
|
||||
);
|
||||
} else if (property.type === 'TSTypeLiteral') {
|
||||
return flattenProperties(property.members, types);
|
||||
return flattenProperties(property.members, types, parser);
|
||||
} else if (property.type === 'TSInterfaceDeclaration') {
|
||||
return flattenProperties(getProperties(property.id.name, types), types);
|
||||
return flattenProperties(
|
||||
parser.getProperties(property.id.name, types),
|
||||
types,
|
||||
parser,
|
||||
);
|
||||
} else if (property.type === 'TSIntersectionType') {
|
||||
return flattenProperties(property.types, types);
|
||||
return flattenProperties(property.types, types, parser);
|
||||
} else {
|
||||
throw new Error(
|
||||
`${property.type} is not a supported object literal type.`,
|
||||
|
@ -544,7 +521,6 @@ function flattenProperties(
|
|||
}
|
||||
|
||||
module.exports = {
|
||||
getProperties,
|
||||
getSchemaInfo,
|
||||
getTypeAnnotation,
|
||||
flattenProperties,
|
||||
|
|
|
@ -183,7 +183,7 @@ function findEventArgumentsAndType(
|
|||
} {
|
||||
if (typeAnnotation.type === 'TSInterfaceDeclaration') {
|
||||
return {
|
||||
argumentProps: flattenProperties([typeAnnotation], types),
|
||||
argumentProps: flattenProperties([typeAnnotation], types, parser),
|
||||
paperTopLevelNameDeprecated: paperName,
|
||||
bubblingType,
|
||||
};
|
||||
|
|
|
@ -15,7 +15,6 @@ import type {ComponentSchemaBuilderConfig} from '../../schema.js';
|
|||
const {getCommands} = require('./commands');
|
||||
const {getEvents} = require('./events');
|
||||
const {categorizeProps} = require('./extends');
|
||||
const {getProperties} = require('./componentsUtils.js');
|
||||
const {
|
||||
getOptions,
|
||||
findComponentConfig,
|
||||
|
@ -37,7 +36,7 @@ function buildComponentSchema(
|
|||
|
||||
const types = parser.getTypes(ast);
|
||||
|
||||
const propProperties = getProperties(propsTypeName, types);
|
||||
const propProperties = parser.getProperties(propsTypeName, types);
|
||||
|
||||
const commandProperties = getCommandProperties(ast, parser);
|
||||
|
||||
|
|
|
@ -270,7 +270,7 @@ function translateTypeAnnotation(
|
|||
return translateObjectTypeAnnotation(
|
||||
hasteModuleName,
|
||||
nullable,
|
||||
flattenProperties([typeAnnotation], types),
|
||||
flattenProperties([typeAnnotation], types, parser),
|
||||
typeResolutionStatus,
|
||||
baseTypes,
|
||||
types,
|
||||
|
@ -288,6 +288,7 @@ function translateTypeAnnotation(
|
|||
flattenProperties(
|
||||
flattenIntersectionType(typeAnnotation, types),
|
||||
types,
|
||||
parser,
|
||||
),
|
||||
typeResolutionStatus,
|
||||
[],
|
||||
|
|
|
@ -510,7 +510,7 @@ class TypeScriptParser implements Parser {
|
|||
}
|
||||
|
||||
// find events and props
|
||||
for (const prop of flattenProperties(remaining, types)) {
|
||||
for (const prop of flattenProperties(remaining, types, this)) {
|
||||
const topLevelType = parseTopLevelType(
|
||||
prop.typeAnnotation.typeAnnotation,
|
||||
types,
|
||||
|
@ -532,6 +532,33 @@ class TypeScriptParser implements Parser {
|
|||
extendsProps,
|
||||
};
|
||||
}
|
||||
|
||||
getProperties(typeName: string, types: TypeDeclarationMap): $FlowFixMe {
|
||||
const alias = types[typeName];
|
||||
if (!alias) {
|
||||
throw new Error(
|
||||
`Failed to find definition for "${typeName}", please check that you have a valid codegen typescript file`,
|
||||
);
|
||||
}
|
||||
const aliasKind =
|
||||
alias.type === 'TSInterfaceDeclaration' ? 'interface' : 'type';
|
||||
|
||||
try {
|
||||
if (aliasKind === 'interface') {
|
||||
return [...(alias.extends ?? []), ...alias.body.body];
|
||||
}
|
||||
|
||||
return (
|
||||
alias.typeAnnotation.members ||
|
||||
alias.typeAnnotation.typeParameters.params[0].members ||
|
||||
alias.typeAnnotation.typeParameters.params
|
||||
);
|
||||
} catch (e) {
|
||||
throw new Error(
|
||||
`Failed to find ${aliasKind} definition for "${typeName}", please check that you have a valid codegen typescript file`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
|
Загрузка…
Ссылка в новой задаче