Extract the function createParserErrorCapturer into a single function in the parsers/utils.js file (#34934)

Summary:
This PR aims to reduce code duplication by extracting `createParserErrorCapturer` function from the flow and typescript folders into a shared parsers/utils.js file. It is a task of https://github.com/facebook/react-native/issues/34872:
> Extract the function createParserErrorCapturer ([Flow](https://github.com/facebook/react-native/blob/main/packages/react-native-codegen/src/parsers/flow/utils.js#L122-L143) [TypeScript](https://github.com/facebook/react-native/blob/main/packages/react-native-codegen/src/parsers/typescript/utils.js#L114-L135)) into a single function in the parsers/utils.js file and replace its invocation with this new function.

## Changelog

<!-- Help reviewers and the release process by writing your own changelog entry. For an example, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->
[Internal] [Changed] - Extract the function createParserErrorCapturer into a single function in the parsers/utils.js file

Pull Request resolved: https://github.com/facebook/react-native/pull/34934

Test Plan:
yarn flow:
<img width="628" alt="image" src="https://user-images.githubusercontent.com/40902940/194948886-d6763e39-ea07-4004-86cc-5287c4783012.png">

yarn lint:
<img width="509" alt="image" src="https://user-images.githubusercontent.com/40902940/194948916-3e54afa5-7e0b-4a61-ac18-8ec306d8c6d4.png">

yarn jest react-native-codegen:
<img width="386" alt="image" src="https://user-images.githubusercontent.com/40902940/194948966-d1e5b12e-02ab-4d53-a4bf-6abaf4d70fbe.png">

Reviewed By: cipolleschi

Differential Revision: D40256048

Pulled By: cipolleschi

fbshipit-source-id: 098519a17d6e3128d236c639b246a706f9dbf66d
This commit is contained in:
MaeIg 2022-10-11 05:24:25 -07:00 коммит произвёл Facebook GitHub Bot
Родитель 966f3cdea3
Коммит 38fcafe623
9 изменённых файлов: 93 добавлений и 68 удалений

Просмотреть файл

@ -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');
});
}
}

Просмотреть файл

@ -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);
});
});
});

Просмотреть файл

@ -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(

Просмотреть файл

@ -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 {

Просмотреть файл

@ -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 = <T>(fn: () => T) => ?T;
function createParserErrorCapturer(): [
Array<ParserError>,
ParserErrorCapturer,
] {
const errors = [];
function guard<T>(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,

Просмотреть файл

@ -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(

Просмотреть файл

@ -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 {

Просмотреть файл

@ -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 = <T>(fn: () => T) => ?T;
function createParserErrorCapturer(): [
Array<ParserError>,
ParserErrorCapturer,
] {
const errors = [];
function guard<T>(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,

Просмотреть файл

@ -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 = <T>(fn: () => T) => ?T;
function createParserErrorCapturer(): [
Array<ParserError>,
ParserErrorCapturer,
] {
const errors = [];
function guard<T>(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,
};