Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/eslint-plugin-specs/react-native-modules.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand All @@ -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');
});
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand Down Expand Up @@ -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);
});
});
});
11 changes: 5 additions & 6 deletions packages/react-native-codegen/src/parsers/flow/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
26 changes: 0 additions & 26 deletions packages/react-native-codegen/src/parsers/flow/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -213,7 +188,6 @@ function isModuleRegistryCall(node: $FlowFixMe): boolean {
module.exports = {
getValueFromTypes,
resolveTypeAnnotation,
createParserErrorCapturer,
getTypes,
visit,
isModuleRegistryCall,
Expand Down
11 changes: 5 additions & 6 deletions packages/react-native-codegen/src/parsers/typescript/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
25 changes: 0 additions & 25 deletions packages/react-native-codegen/src/parsers/typescript/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@

import type {TypeAliasResolutionStatus} from '../utils';

const {ParserError} = require('../errors');
const {parseTopLevelType} = require('./parseTopLevelType');

/**
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -204,7 +180,6 @@ function isModuleRegistryCall(node: $FlowFixMe): boolean {

module.exports = {
resolveTypeAnnotation,
createParserErrorCapturer,
getTypes,
visit,
isModuleRegistryCall,
Expand Down
26 changes: 26 additions & 0 deletions packages/react-native-codegen/src/parsers/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

'use strict';

const {ParserError} = require('./errors');

const path = require('path');

export type TypeAliasResolutionStatus =
Expand All @@ -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,
};