diff --git a/packages/react-native-codegen/src/parsers/flow/components/index.js b/packages/react-native-codegen/src/parsers/flow/components/index.js index f3b9f4770fb..8c68c98d650 100644 --- a/packages/react-native-codegen/src/parsers/flow/components/index.js +++ b/packages/react-native-codegen/src/parsers/flow/components/index.js @@ -16,6 +16,7 @@ const {getEvents} = require('./events'); const {getProps, getPropProperties} = require('./props'); const {getCommandOptions, getOptions} = require('./options'); const {getExtendsProps, removeKnownExtends} = require('./extends'); +const {getTypes} = require('../utils'); function findComponentConfig(ast) { const foundConfigs = []; @@ -167,7 +168,7 @@ function getCommandProperties(commandTypeName, types, commandOptions) { } // $FlowFixMe there's no flowtype for AST -function buildComponentSchema(ast, types): ComponentSchemaBuilderConfig { +function buildComponentSchema(ast): ComponentSchemaBuilderConfig { const { componentName, propsTypeName, @@ -176,6 +177,8 @@ function buildComponentSchema(ast, types): ComponentSchemaBuilderConfig { optionsExpression, } = findComponentConfig(ast); + const types = getTypes(ast); + const propProperties = getPropProperties(propsTypeName, types); const commandOptions = getCommandOptions(commandOptionsExpression); diff --git a/packages/react-native-codegen/src/parsers/flow/index.js b/packages/react-native-codegen/src/parsers/flow/index.js index ab3a9d4a595..43d0f854bc9 100644 --- a/packages/react-native-codegen/src/parsers/flow/index.js +++ b/packages/react-native-codegen/src/parsers/flow/index.js @@ -21,27 +21,6 @@ const {buildModuleSchema} = require('./modules'); const {wrapModuleSchema} = require('./modules/schema'); const invariant = require('invariant'); -import type {TypeDeclarationMap} from './utils'; - -function getTypes(ast): TypeDeclarationMap { - return ast.body.reduce((types, node) => { - if (node.type === 'ExportNamedDeclaration' && node.exportKind === 'type') { - if ( - node.declaration.type === 'TypeAlias' || - node.declaration.type === 'InterfaceDeclaration' - ) { - types[node.declaration.id.name] = node.declaration; - } - } else if ( - node.type === 'TypeAlias' || - node.type === 'InterfaceDeclaration' - ) { - types[node.id.name] = node; - } - return types; - }, {}); -} - function isComponent(ast) { const defaultExports = ast.body.filter( node => node.type === 'ExportDefaultDeclaration', @@ -68,27 +47,39 @@ function isComponent(ast) { ); } -function isModule(types: TypeDeclarationMap) { - const declaredModuleNames: Array = Object.keys(types).filter( - (typeName: string) => { - const declaration = types[typeName]; +function isModule( + // TODO(T71778680): Flow-type this node. + ast: $FlowFixMe, +) { + const moduleInterfaces = ast.body + .map(node => { + if ( + node.type === 'ExportNamedDeclaration' && + node.exportKind === 'type' && + node.declaration.type === 'InterfaceDeclaration' + ) { + return node.declaration; + } + return node; + }) + .filter(declaration => { return ( declaration.type === 'InterfaceDeclaration' && declaration.extends.length === 1 && declaration.extends[0].type === 'InterfaceExtends' && declaration.extends[0].id.name === 'TurboModule' ); - }, - ); + }) + .map(declaration => declaration.id.name); - if (declaredModuleNames.length === 0) { + if (moduleInterfaces.length === 0) { return false; } - if (declaredModuleNames.length > 1) { + if (moduleInterfaces.length > 1) { throw new Error( 'File contains declarations of more than one module: ' + - declaredModuleNames.join(', ') + + moduleInterfaces.join(', ') + '. Please declare exactly one module in this file.', ); } @@ -96,9 +87,12 @@ function isModule(types: TypeDeclarationMap) { return true; } -function getConfigType(ast, types: TypeDeclarationMap): 'module' | 'component' { +function getConfigType( + // TODO(T71778680): Flow-type this node. + ast: $FlowFixMe, +): 'module' | 'component' { const isConfigAComponent = isComponent(ast); - const isConfigAModule = isModule(types); + const isConfigAModule = isModule(ast); if (isConfigAModule && isConfigAComponent) { throw new Error( @@ -142,12 +136,10 @@ const TURBO_MODULE_REGISTRY_REQUIRE_REGEX_STRING = withSpace( function buildSchema(contents: string, filename: ?string): SchemaType { const ast = flowParser.parse(contents); - const types = getTypes(ast); - - const configType = getConfigType(ast, types); + const configType = getConfigType(ast); if (configType === 'component') { - return wrapComponentSchema(buildComponentSchema(ast, types)); + return wrapComponentSchema(buildComponentSchema(ast)); } else { if (filename === undefined || filename === null) { throw new Error('Filepath expected while parasing a module'); @@ -180,7 +172,7 @@ function buildSchema(contents: string, filename: ?string): SchemaType { } return wrapModuleSchema( - buildModuleSchema(hasteModuleName, moduleNames, types), + buildModuleSchema(hasteModuleName, moduleNames, ast), hasteModuleName, ); } diff --git a/packages/react-native-codegen/src/parsers/flow/modules/index.js b/packages/react-native-codegen/src/parsers/flow/modules/index.js index 719508f92d7..1f533e379e1 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/index.js +++ b/packages/react-native-codegen/src/parsers/flow/modules/index.js @@ -22,7 +22,7 @@ import type { } from '../../../CodegenSchema.js'; import type {TypeDeclarationMap} from '../utils.js'; -const {resolveTypeAnnotation} = require('../utils.js'); +const {resolveTypeAnnotation, getTypes} = require('../utils.js'); const {unwrapNullable, wrapNullable} = require('./utils'); const { FlowGenericNotTypeParameterizedParserError, @@ -398,8 +398,12 @@ function buildPropertySchema( function buildModuleSchema( hasteModuleName: string, moduleNames: $ReadOnlyArray, - types: TypeDeclarationMap, + /** + * TODO(T71778680): Flow-type this node. + */ + ast: $FlowFixMe, ): NativeModuleSchema { + const types = getTypes(ast); const moduleInterfaceNames = (Object.keys( types, ): $ReadOnlyArray).filter((typeName: string) => { diff --git a/packages/react-native-codegen/src/parsers/flow/utils.js b/packages/react-native-codegen/src/parsers/flow/utils.js index 15b13c59499..e000d2db952 100644 --- a/packages/react-native-codegen/src/parsers/flow/utils.js +++ b/packages/react-native-codegen/src/parsers/flow/utils.js @@ -20,6 +20,25 @@ */ export type TypeDeclarationMap = {|[declarationName: string]: $FlowFixMe|}; +function getTypes(ast: $FlowFixMe): TypeDeclarationMap { + return ast.body.reduce((types, node) => { + if (node.type === 'ExportNamedDeclaration' && node.exportKind === 'type') { + if ( + node.declaration.type === 'TypeAlias' || + node.declaration.type === 'InterfaceDeclaration' + ) { + types[node.declaration.id.name] = node.declaration; + } + } else if ( + node.type === 'TypeAlias' || + node.type === 'InterfaceDeclaration' + ) { + types[node.id.name] = node; + } + return types; + }, {}); +} + // $FlowFixMe there's no flowtype for ASTs export type ASTNode = Object; @@ -95,4 +114,5 @@ function getValueFromTypes(value: ASTNode, types: TypeDeclarationMap): ASTNode { module.exports = { getValueFromTypes, resolveTypeAnnotation, + getTypes, };