create throwIfPartialNotAnnotatingTypeParameter and add extractAnnotatedElement method in parsers (#36272)

Summary:
> Create a throwIfPartialNotAnnotatingTypeParameter function in the error-utils.js file and extract the error-emitting code from [Flow](https://github.com/facebook/react-native/blob/main/packages/react-native-codegen/src/parsers/flow/modules/index.js#L174-L178) and [Typescript](https://github.com/facebook/react-native/blob/main/packages/react-native-codegen/src/parsers/typescript/modules/index.js#L252-L259) index files. Notice that the way in which the annotatedElement is computed is different, therefore we should add an extractAnnotatedElement function to the Flow and TypeScript parsers.

Part of the Codegen ☂️ Issue https://github.com/facebook/react-native/issues/34872

## Changelog

<!-- Help reviewers and the release process by writing your own changelog entry.

Pick one each for the category and type tags:

[ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message

For more details, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->
[Internal] [Changed] - create throwIfPartialNotAnnotatingTypeParameter and add extractAnnotatedElement method in parsers

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

Test Plan: `yarn jest react-native-codegen`

Reviewed By: cipolleschi

Differential Revision: D43564134

Pulled By: rshest

fbshipit-source-id: 89a6567340a560d7b6c353cfff8a43e2dd0f76cc
This commit is contained in:
Tarun Chauhan
2023-02-24 08:00:20 -08:00
committed by Facebook GitHub Bot
parent e106a62b1a
commit 371e263847
8 changed files with 150 additions and 14 deletions
@@ -25,6 +25,7 @@ const {
throwIfUntypedModule,
throwIfUnsupportedFunctionParamTypeAnnotationParserError,
throwIfArrayElementTypeAnnotationIsUnsupported,
throwIfPartialNotAnnotatingTypeParameter,
} = require('../error-utils');
const {
UnsupportedModulePropertyParserError,
@@ -720,3 +721,78 @@ describe('throwIfArrayElementTypeAnnotationIsUnsupported', () => {
}).not.toThrow(UnsupportedArrayElementTypeAnnotationParserError);
});
});
describe('throwIfPartialNotAnnotatingTypeParameter', () => {
const flowParser = new FlowParser();
const typescriptParser = new TypeScriptParser();
const typerscriptTypeAnnotation = {
typeParameters: {
params: [
{
typeName: {
name: 'TypeDeclaration',
},
},
],
},
};
const flowTypeAnnotation = {
typeParameters: {
params: [
{
id: {
name: 'TypeDeclaration',
},
},
],
},
};
it('throw error if Partial Not Annotating Type Parameter in Flow', () => {
const types = {};
expect(() => {
throwIfPartialNotAnnotatingTypeParameter(
flowTypeAnnotation,
types,
flowParser,
);
}).toThrowError('Partials only support annotating a type parameter.');
});
it('throw error if Partial Not Annotating Type Parameter in TypeScript', () => {
const types = {};
expect(() => {
throwIfPartialNotAnnotatingTypeParameter(
typerscriptTypeAnnotation,
types,
typescriptParser,
);
}).toThrowError('Partials only support annotating a type parameter.');
});
it('does not throw error if Partial Annotating Type Parameter in Flow', () => {
const types = {TypeDeclaration: {}};
expect(() => {
throwIfPartialNotAnnotatingTypeParameter(
flowTypeAnnotation,
types,
flowParser,
);
}).not.toThrowError();
});
it('does not throw error if Partial Annotating Type Parameter in TypeScript', () => {
const types = {TypeDeclaration: {}};
expect(() => {
throwIfPartialNotAnnotatingTypeParameter(
typerscriptTypeAnnotation,
types,
typescriptParser,
);
}).not.toThrowError();
});
});
@@ -13,6 +13,7 @@
import type {NativeModuleTypeAnnotation} from '../CodegenSchema';
import type {ParserType} from './errors';
import type {Parser} from './parser';
import type {TypeDeclarationMap} from '../parsers/utils';
const {
MisnamedModuleInterfaceParserError,
@@ -280,6 +281,21 @@ function throwIfIncorrectModuleRegistryCallArgument(
}
}
function throwIfPartialNotAnnotatingTypeParameter(
typeAnnotation: $FlowFixMe,
types: TypeDeclarationMap,
parser: Parser,
) {
const annotatedElement = parser.extractAnnotatedElement(
typeAnnotation,
types,
);
if (!annotatedElement) {
throw new Error('Partials only support annotating a type parameter.');
}
}
module.exports = {
throwIfModuleInterfaceIsMisnamed,
throwIfUnsupportedFunctionReturnTypeAnnotationParserError,
@@ -295,4 +311,5 @@ module.exports = {
throwIfUnsupportedFunctionParamTypeAnnotationParserError,
throwIfArrayElementTypeAnnotationIsUnsupported,
throwIfIncorrectModuleRegistryCallArgument,
throwIfPartialNotAnnotatingTypeParameter,
};
@@ -69,6 +69,7 @@ const {
throwIfIncorrectModuleRegistryCallArgument,
throwIfUntypedModule,
throwIfMoreThanOneModuleInterfaceParserError,
throwIfPartialNotAnnotatingTypeParameter,
} = require('../../error-utils');
const language = 'Flow';
@@ -168,14 +169,16 @@ function translateTypeAnnotation(
);
}
const annotatedElement =
types[typeAnnotation.typeParameters.params[0].id.name];
const annotatedElement = parser.extractAnnotatedElement(
typeAnnotation,
types,
);
if (!annotatedElement) {
throw new Error(
'Partials only support annotating a type parameter.',
);
}
throwIfPartialNotAnnotatingTypeParameter(
typeAnnotation,
types,
parser,
);
const properties = annotatedElement.right.properties.map(prop => {
return {
@@ -21,6 +21,7 @@ import type {
} from '../../CodegenSchema';
import type {ParserType} from '../errors';
import type {Parser} from '../parser';
import type {TypeDeclarationMap} from '../utils';
// $FlowFixMe[untyped-import] there's no flowtype flow-parser
const flowParser = require('flow-parser');
@@ -205,6 +206,13 @@ class FlowParser implements Parser {
node.extends[0].id.name === 'TurboModule'
);
}
extractAnnotatedElement(
typeAnnotation: $FlowFixMe,
types: TypeDeclarationMap,
): $FlowFixMe {
return types[typeAnnotation.typeParameters.params[0].id.name];
}
}
module.exports = {
+12
View File
@@ -20,6 +20,7 @@ import type {
NativeModuleEnumMembers,
} from '../CodegenSchema';
import type {ParserType} from './errors';
import type {TypeDeclarationMap} from './utils';
/**
* This is the main interface for Parsers of various languages.
@@ -157,4 +158,15 @@ export interface Parser {
* Given a node, it returns true if it is a module interface
*/
isModuleInterface(node: $FlowFixMe): boolean;
/**
* Given a typeAnnotation, it returns the annotated element.
* @paramater typeAnnotation: the annotation for a type.
* @paramater types: a map of type declarations.
* @returns: the annotated element.
*/
extractAnnotatedElement(
typeAnnotation: $FlowFixMe,
types: TypeDeclarationMap,
): $FlowFixMe;
}
@@ -22,6 +22,8 @@ import type {
NativeModuleEnumMembers,
} from '../CodegenSchema';
import type {TypeDeclarationMap} from './utils';
// $FlowFixMe[untyped-import] there's no flowtype flow-parser
const flowParser = require('flow-parser');
const {
@@ -168,4 +170,11 @@ export class MockedParser implements Parser {
node.extends[0].id.name === 'TurboModule'
);
}
extractAnnotatedElement(
typeAnnotation: $FlowFixMe,
types: TypeDeclarationMap,
): $FlowFixMe {
return types[typeAnnotation.typeParameters.params[0].id.name];
}
}
@@ -75,6 +75,7 @@ const {
throwIfMoreThanOneModuleInterfaceParserError,
throwIfIncorrectModuleRegistryCallTypeParameterParserError,
throwIfIncorrectModuleRegistryCallArgument,
throwIfPartialNotAnnotatingTypeParameter,
} = require('../../error-utils');
const language = 'TypeScript';
@@ -249,14 +250,16 @@ function translateTypeAnnotation(
);
}
const annotatedElement =
types[typeAnnotation.typeParameters.params[0].typeName.name];
const annotatedElement = parser.extractAnnotatedElement(
typeAnnotation,
types,
);
if (!annotatedElement) {
throw new Error(
'Partials only support annotating a type parameter.',
);
}
throwIfPartialNotAnnotatingTypeParameter(
typeAnnotation,
types,
parser,
);
const properties = annotatedElement.typeAnnotation.members.map(
member => {
@@ -21,6 +21,7 @@ import type {
} from '../../CodegenSchema';
import type {ParserType} from '../errors';
import type {Parser} from '../parser';
import type {TypeDeclarationMap} from '../utils';
// $FlowFixMe[untyped-import] Use flow-types for @babel/parser
const babelParser = require('@babel/parser');
@@ -201,6 +202,13 @@ class TypeScriptParser implements Parser {
node.extends[0].expression.name === 'TurboModule'
);
}
extractAnnotatedElement(
typeAnnotation: $FlowFixMe,
types: TypeDeclarationMap,
): $FlowFixMe {
return types[typeAnnotation.typeParameters.params[0].typeName.name];
}
}
module.exports = {
TypeScriptParser,