diff --git a/packages/eslint-plugin-specs/react-native-modules.js b/packages/eslint-plugin-specs/react-native-modules.js index 43d83fb6953cb4..f303ab539eba12 100644 --- a/packages/eslint-plugin-specs/react-native-modules.js +++ b/packages/eslint-plugin-specs/react-native-modules.js @@ -35,7 +35,7 @@ function requireModuleParser() { withBabelRegister(config, () => { RNModuleParser = require('react-native-codegen/src/parsers/flow/modules'); - RNParserUtils = require('react-native-codegen/src/parsers/flow/utils'); + RNParserUtils = require('react-native-codegen/src/parsers/utils'); }); } else { const config = { @@ -45,7 +45,7 @@ function requireModuleParser() { withBabelRegister(config, () => { RNModuleParser = require('react-native-codegen/lib/parsers/flow/modules'); - RNParserUtils = require('react-native-codegen/lib/parsers/flow/utils'); + RNParserUtils = require('react-native-codegen/lib/parsers/utils'); }); } } diff --git a/packages/react-native-codegen/src/parsers/__tests__/utils-test.js b/packages/react-native-codegen/src/parsers/__tests__/utils-test.js index 72e170cbf7ffab..349bd46a92e593 100644 --- a/packages/react-native-codegen/src/parsers/__tests__/utils-test.js +++ b/packages/react-native-codegen/src/parsers/__tests__/utils-test.js @@ -4,12 +4,18 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * + * @flow strict-local * @format * @oncall react_native */ 'use strict'; -const {extractNativeModuleName} = require('../utils.js'); + +const { + extractNativeModuleName, + createParserErrorCapturer, +} = require('../utils.js'); +const {ParserError} = require('../errors'); describe('extractnativeModuleName', () => { it('return filename when it ends with .js', () => { @@ -63,3 +69,49 @@ describe('extractnativeModuleName', () => { expect(nativeModuleName).toBe('NativeModule'); }); }); + +describe('createParserErrorCapturer', () => { + describe("when function doesn't throw", () => { + it("returns result and doesn't change errors array", () => { + const [errors, guard] = createParserErrorCapturer(); + const fn = () => 'result'; + + const result = guard(fn); + expect(result).toBe('result'); + expect(errors).toHaveLength(0); + }); + }); + + describe('when function throws a ParserError', () => { + it('returns null and adds the error in errors array instead of throwing it', () => { + const [errors, guard] = createParserErrorCapturer(); + const ErrorThrown = new ParserError( + 'moduleName', + null, + 'Something went wrong :(', + ); + const fn = () => { + throw ErrorThrown; + }; + + const result = guard(fn); + expect(result).toBe(null); + expect(errors).toHaveLength(1); + expect(errors[0]).toEqual(ErrorThrown); + expect(() => guard(fn)).not.toThrow(); + }); + }); + + describe('when function throws another error', () => { + it("throws the error and doesn't change errors array", () => { + const [errors, guard] = createParserErrorCapturer(); + const errorMessage = 'Something else went wrong :('; + const fn = () => { + throw new Error(errorMessage); + }; + + expect(() => guard(fn)).toThrow(errorMessage); + expect(errors).toHaveLength(0); + }); + }); +}); diff --git a/packages/react-native-codegen/src/parsers/flow/index.js b/packages/react-native-codegen/src/parsers/flow/index.js index 506340e5b0eb0d..61b5273ead8bff 100644 --- a/packages/react-native-codegen/src/parsers/flow/index.js +++ b/packages/react-native-codegen/src/parsers/flow/index.js @@ -14,16 +14,15 @@ import type {SchemaType} from '../../CodegenSchema.js'; // $FlowFixMe[untyped-import] there's no flowtype flow-parser const flowParser = require('flow-parser'); const fs = require('fs'); -const {extractNativeModuleName} = require('../utils.js'); +const { + extractNativeModuleName, + createParserErrorCapturer, +} = require('../utils.js'); const {buildComponentSchema} = require('./components'); const {wrapComponentSchema} = require('./components/schema'); const {buildModuleSchema} = require('./modules'); const {wrapModuleSchema} = require('../parsers-commons'); -const { - createParserErrorCapturer, - visit, - isModuleRegistryCall, -} = require('./utils'); +const {visit, isModuleRegistryCall} = require('./utils'); const invariant = require('invariant'); function getConfigType( 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 8ffd9db1623081..3597f261498dea 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/index.js +++ b/packages/react-native-codegen/src/parsers/flow/modules/index.js @@ -23,7 +23,7 @@ import type { } from '../../../CodegenSchema.js'; import type {TypeDeclarationMap} from '../utils.js'; -import type {ParserErrorCapturer} from '../utils'; +import type {ParserErrorCapturer} from '../../utils'; import type {NativeModuleTypeAnnotation} from '../../../CodegenSchema.js'; const { diff --git a/packages/react-native-codegen/src/parsers/flow/utils.js b/packages/react-native-codegen/src/parsers/flow/utils.js index 6c8b72c10e8230..26272346f8305d 100644 --- a/packages/react-native-codegen/src/parsers/flow/utils.js +++ b/packages/react-native-codegen/src/parsers/flow/utils.js @@ -12,8 +12,6 @@ import type {TypeAliasResolutionStatus} from '../utils'; -const {ParserError} = require('../errors'); - /** * This FlowFixMe is supposed to refer to an InterfaceDeclaration or TypeAlias * declaration type. Unfortunately, we don't have those types, because flow-parser @@ -119,29 +117,6 @@ function getValueFromTypes(value: ASTNode, types: TypeDeclarationMap): ASTNode { return value; } -export type ParserErrorCapturer = (fn: () => T) => ?T; - -function createParserErrorCapturer(): [ - Array, - ParserErrorCapturer, -] { - const errors = []; - function guard(fn: () => T): ?T { - try { - return fn(); - } catch (error) { - if (!(error instanceof ParserError)) { - throw error; - } - errors.push(error); - - return null; - } - } - - return [errors, guard]; -} - // TODO(T71778680): Flow-type ASTNodes. function visit( astNode: $FlowFixMe, @@ -213,7 +188,6 @@ function isModuleRegistryCall(node: $FlowFixMe): boolean { module.exports = { getValueFromTypes, resolveTypeAnnotation, - createParserErrorCapturer, getTypes, visit, isModuleRegistryCall, diff --git a/packages/react-native-codegen/src/parsers/typescript/index.js b/packages/react-native-codegen/src/parsers/typescript/index.js index cdd3b0ab6660b0..b713ed2eb4af5a 100644 --- a/packages/react-native-codegen/src/parsers/typescript/index.js +++ b/packages/react-native-codegen/src/parsers/typescript/index.js @@ -13,17 +13,16 @@ import type {SchemaType} from '../../CodegenSchema.js'; const babelParser = require('@babel/parser'); const fs = require('fs'); -const {extractNativeModuleName} = require('../utils.js'); +const { + extractNativeModuleName, + createParserErrorCapturer, +} = require('../utils.js'); const {buildComponentSchema} = require('./components'); const {wrapComponentSchema} = require('./components/schema'); const {buildModuleSchema} = require('./modules'); const {wrapModuleSchema} = require('../parsers-commons'); -const { - createParserErrorCapturer, - visit, - isModuleRegistryCall, -} = require('./utils'); +const {visit, isModuleRegistryCall} = require('./utils'); const invariant = require('invariant'); function getConfigType( 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 c6dbbb9ef7f343..5d73f31d5f61ec 100644 --- a/packages/react-native-codegen/src/parsers/typescript/modules/index.js +++ b/packages/react-native-codegen/src/parsers/typescript/modules/index.js @@ -23,7 +23,7 @@ import type { } from '../../../CodegenSchema.js'; import type {TypeDeclarationMap} from '../utils.js'; -import type {ParserErrorCapturer} from '../utils'; +import type {ParserErrorCapturer} from '../../utils'; import type {NativeModuleTypeAnnotation} from '../../../CodegenSchema.js'; const { diff --git a/packages/react-native-codegen/src/parsers/typescript/utils.js b/packages/react-native-codegen/src/parsers/typescript/utils.js index 87ca0bed7f860a..82fefa66dcfd1e 100644 --- a/packages/react-native-codegen/src/parsers/typescript/utils.js +++ b/packages/react-native-codegen/src/parsers/typescript/utils.js @@ -12,7 +12,6 @@ import type {TypeAliasResolutionStatus} from '../utils'; -const {ParserError} = require('../errors'); const {parseTopLevelType} = require('./parseTopLevelType'); /** @@ -111,29 +110,6 @@ function resolveTypeAnnotation( }; } -export type ParserErrorCapturer = (fn: () => T) => ?T; - -function createParserErrorCapturer(): [ - Array, - ParserErrorCapturer, -] { - const errors = []; - function guard(fn: () => T): ?T { - try { - return fn(); - } catch (error) { - if (!(error instanceof ParserError)) { - throw error; - } - errors.push(error); - - return null; - } - } - - return [errors, guard]; -} - // TODO(T108222691): Use flow-types for @babel/parser function visit( astNode: $FlowFixMe, @@ -204,7 +180,6 @@ function isModuleRegistryCall(node: $FlowFixMe): boolean { module.exports = { resolveTypeAnnotation, - createParserErrorCapturer, getTypes, visit, isModuleRegistryCall, diff --git a/packages/react-native-codegen/src/parsers/utils.js b/packages/react-native-codegen/src/parsers/utils.js index 0aabd8b816732f..39b6e2ce5b1f34 100644 --- a/packages/react-native-codegen/src/parsers/utils.js +++ b/packages/react-native-codegen/src/parsers/utils.js @@ -10,6 +10,8 @@ 'use strict'; +const {ParserError} = require('./errors'); + const path = require('path'); export type TypeAliasResolutionStatus = @@ -27,6 +29,30 @@ function extractNativeModuleName(filename: string): string { return path.basename(filename).split('.')[0]; } +export type ParserErrorCapturer = (fn: () => T) => ?T; + +function createParserErrorCapturer(): [ + Array, + ParserErrorCapturer, +] { + const errors = []; + function guard(fn: () => T): ?T { + try { + return fn(); + } catch (error) { + if (!(error instanceof ParserError)) { + throw error; + } + errors.push(error); + + return null; + } + } + + return [errors, guard]; +} + module.exports = { extractNativeModuleName, + createParserErrorCapturer, };