diff --git a/packages/react-native-codegen/src/parsers/__tests__/parsers-test.js b/packages/react-native-codegen/src/parsers/__tests__/parsers-test.js index b982faaad0..40549fbd8b 100644 --- a/packages/react-native-codegen/src/parsers/__tests__/parsers-test.js +++ b/packages/react-native-codegen/src/parsers/__tests__/parsers-test.js @@ -67,6 +67,28 @@ describe('FlowParser', () => { ]); }); }); + + describe('isModuleInterface', () => { + it('returns true if it is a valid node', () => { + const node = { + type: 'InterfaceDeclaration', + extends: [ + { + type: 'InterfaceExtends', + id: { + name: 'TurboModule', + }, + }, + ], + }; + expect(parser.isModuleInterface(node)).toBe(true); + }); + + it('returns false if it is a invalid node', () => { + const node = {}; + expect(parser.isModuleInterface(node)).toBe(false); + }); + }); }); describe('TypeScriptParser', () => { @@ -116,4 +138,26 @@ describe('TypeScriptParser', () => { ]); }); }); + + describe('isModuleInterface', () => { + it('returns true if it is a valid node', () => { + const node = { + type: 'TSInterfaceDeclaration', + extends: [ + { + type: 'TSExpressionWithTypeArguments', + expression: { + name: 'TurboModule', + }, + }, + ], + }; + expect(parser.isModuleInterface(node)).toBe(true); + }); + + it('returns false if it is a invalid node', () => { + const node = {}; + expect(parser.isModuleInterface(node)).toBe(false); + }); + }); }); 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 6fa83c5bf9..f4c24fcd8f 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/index.js +++ b/packages/react-native-codegen/src/parsers/flow/modules/index.js @@ -330,15 +330,6 @@ function translateTypeAnnotation( } } -function isModuleInterface(node: $FlowFixMe) { - return ( - node.type === 'InterfaceDeclaration' && - node.extends.length === 1 && - node.extends[0].type === 'InterfaceExtends' && - node.extends[0].id.name === 'TurboModule' - ); -} - function buildModuleSchema( hasteModuleName: string, /** @@ -350,7 +341,7 @@ function buildModuleSchema( ): NativeModuleSchema { const types = getTypes(ast); const moduleSpecs = (Object.values(types): $ReadOnlyArray<$FlowFixMe>).filter( - isModuleInterface, + t => parser.isModuleInterface(t), ); throwIfModuleInterfaceNotFound( diff --git a/packages/react-native-codegen/src/parsers/flow/parser.js b/packages/react-native-codegen/src/parsers/flow/parser.js index 1e12d7daae..4eafbdebcb 100644 --- a/packages/react-native-codegen/src/parsers/flow/parser.js +++ b/packages/react-native-codegen/src/parsers/flow/parser.js @@ -196,6 +196,15 @@ class FlowParser implements Parser { value: member.init?.value ?? member.id.name, })); } + + isModuleInterface(node: $FlowFixMe): boolean { + return ( + node.type === 'InterfaceDeclaration' && + node.extends.length === 1 && + node.extends[0].type === 'InterfaceExtends' && + node.extends[0].id.name === 'TurboModule' + ); + } } module.exports = { diff --git a/packages/react-native-codegen/src/parsers/parser.js b/packages/react-native-codegen/src/parsers/parser.js index 52755f81fc..5520deccd7 100644 --- a/packages/react-native-codegen/src/parsers/parser.js +++ b/packages/react-native-codegen/src/parsers/parser.js @@ -152,4 +152,9 @@ export interface Parser { * Calculates enum's members */ parseEnumMembers(typeAnnotation: $FlowFixMe): NativeModuleEnumMembers; + + /** + * Given a node, it returns true if it is a module interface + */ + isModuleInterface(node: $FlowFixMe): boolean; } diff --git a/packages/react-native-codegen/src/parsers/parserMock.js b/packages/react-native-codegen/src/parsers/parserMock.js index 475920a098..39e45ee1f2 100644 --- a/packages/react-native-codegen/src/parsers/parserMock.js +++ b/packages/react-native-codegen/src/parsers/parserMock.js @@ -159,4 +159,13 @@ export class MockedParser implements Parser { }, ]; } + + isModuleInterface(node: $FlowFixMe): boolean { + return ( + node.type === 'InterfaceDeclaration' && + node.extends.length === 1 && + node.extends[0].type === 'InterfaceExtends' && + node.extends[0].id.name === 'TurboModule' + ); + } } diff --git a/packages/react-native-codegen/src/parsers/typescript/modules/index.js b/packages/react-native-codegen/src/parsers/typescript/modules/index.js index 64cd08459c..8366890ad6 100644 --- a/packages/react-native-codegen/src/parsers/typescript/modules/index.js +++ b/packages/react-native-codegen/src/parsers/typescript/modules/index.js @@ -436,15 +436,6 @@ function translateTypeAnnotation( } } -function isModuleInterface(node: $FlowFixMe) { - return ( - node.type === 'TSInterfaceDeclaration' && - node.extends?.length === 1 && - node.extends[0].type === 'TSExpressionWithTypeArguments' && - node.extends[0].expression.name === 'TurboModule' - ); -} - function buildModuleSchema( hasteModuleName: string, /** @@ -456,7 +447,7 @@ function buildModuleSchema( ): NativeModuleSchema { const types = getTypes(ast); const moduleSpecs = (Object.values(types): $ReadOnlyArray<$FlowFixMe>).filter( - isModuleInterface, + t => parser.isModuleInterface(t), ); throwIfModuleInterfaceNotFound( diff --git a/packages/react-native-codegen/src/parsers/typescript/parser.js b/packages/react-native-codegen/src/parsers/typescript/parser.js index 84b2dc4c15..b200de3bbe 100644 --- a/packages/react-native-codegen/src/parsers/typescript/parser.js +++ b/packages/react-native-codegen/src/parsers/typescript/parser.js @@ -192,6 +192,15 @@ class TypeScriptParser implements Parser { value: member.initializer?.value ?? member.id.name, })); } + + isModuleInterface(node: $FlowFixMe): boolean { + return ( + node.type === 'TSInterfaceDeclaration' && + node.extends?.length === 1 && + node.extends[0].type === 'TSExpressionWithTypeArguments' && + node.extends[0].expression.name === 'TurboModule' + ); + } } module.exports = { TypeScriptParser,