Skip to content

Commit

Permalink
chore: Extract codegen translateFunctionTypeAnnotation into a common …
Browse files Browse the repository at this point in the history
…function (#35182)

Summary:
This PR extracts the codegen `translateFunctionTypeAnnotation` Flow and TypeScript functions into a single common function in the `parsers-primitives.js` file that can be used by both parsers as requested on #34872.

## Changelog

[Internal] [Changed] -  Extract codegen `translateFunctionTypeAnnotation` into a common function in the` parsers-primitives.js` file

Pull Request resolved: #35182

Test Plan:
Run `yarn jest react-native-codegen` and ensure CI is green

![image](https://user-images.githubusercontent.com/11707729/199625849-e89b647f-63fb-40f8-b643-a59dedb4c59a.png)

Reviewed By: cortinico

Differential Revision: D41030544

Pulled By: rshest

fbshipit-source-id: bc93c21e31ed4e8c3293cafe3d808d9f36cf8ecc
  • Loading branch information
gabrieldonadel authored and facebook-github-bot committed Nov 7, 2022
1 parent 6db3995 commit 62244d4
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 192 deletions.
97 changes: 5 additions & 92 deletions packages/react-native-codegen/src/parsers/flow/modules/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ const {
emitStringish,
emitMixedTypeAnnotation,
typeAliasResolution,
translateFunctionTypeAnnotation,
} = require('../../parsers-primitives');

const {
Expand Down Expand Up @@ -355,6 +356,8 @@ function translateTypeAnnotation(
aliasMap,
tryParse,
cxxOnly,
translateTypeAnnotation,
language,
);
return emitFunction(nullable, translateFunctionTypeAnnotationValue);
}
Expand Down Expand Up @@ -385,98 +388,6 @@ function translateTypeAnnotation(
}
}

function translateFunctionTypeAnnotation(
hasteModuleName: string,
// TODO(T71778680): This is a FunctionTypeAnnotation. Type this.
flowFunctionTypeAnnotation: $FlowFixMe,
types: TypeDeclarationMap,
aliasMap: {...NativeModuleAliasMap},
tryParse: ParserErrorCapturer,
cxxOnly: boolean,
): NativeModuleFunctionTypeAnnotation {
type Param = NamedShape<Nullable<NativeModuleParamTypeAnnotation>>;
const params: Array<Param> = [];

for (const flowParam of (flowFunctionTypeAnnotation.params: $ReadOnlyArray<$FlowFixMe>)) {
const parsedParam = tryParse(() => {
if (flowParam.name == null) {
throw new UnnamedFunctionParamParserError(
flowParam,
hasteModuleName,
language,
);
}

const paramName = flowParam.name.name;
const [paramTypeAnnotation, isParamTypeAnnotationNullable] =
unwrapNullable(
translateTypeAnnotation(
hasteModuleName,
flowParam.typeAnnotation,
types,
aliasMap,
tryParse,
cxxOnly,
),
);

if (
paramTypeAnnotation.type === 'VoidTypeAnnotation' ||
paramTypeAnnotation.type === 'PromiseTypeAnnotation'
) {
return throwIfUnsupportedFunctionParamTypeAnnotationParserError(
hasteModuleName,
flowParam.typeAnnotation,
paramName,
paramTypeAnnotation.type,
);
}

return {
name: flowParam.name.name,
optional: flowParam.optional,
typeAnnotation: wrapNullable(
isParamTypeAnnotationNullable,
paramTypeAnnotation,
),
};
});

if (parsedParam != null) {
params.push(parsedParam);
}
}

const [returnTypeAnnotation, isReturnTypeAnnotationNullable] = unwrapNullable(
translateTypeAnnotation(
hasteModuleName,
flowFunctionTypeAnnotation.returnType,
types,
aliasMap,
tryParse,
cxxOnly,
),
);

throwIfUnsupportedFunctionReturnTypeAnnotationParserError(
hasteModuleName,
flowFunctionTypeAnnotation,
'FunctionTypeAnnotation',
language,
cxxOnly,
returnTypeAnnotation.type,
);

return {
type: 'FunctionTypeAnnotation',
returnTypeAnnotation: wrapNullable(
isReturnTypeAnnotationNullable,
returnTypeAnnotation,
),
params,
};
}

function buildPropertySchema(
hasteModuleName: string,
// TODO(T71778680): This is an ObjectTypeProperty containing either:
Expand Down Expand Up @@ -516,6 +427,8 @@ function buildPropertySchema(
aliasMap,
tryParse,
cxxOnly,
translateTypeAnnotation,
language,
),
),
};
Expand Down
148 changes: 147 additions & 1 deletion packages/react-native-codegen/src/parsers/parsers-primitives.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,25 @@ import type {
StringTypeAnnotation,
VoidTypeAnnotation,
NativeModuleFloatTypeAnnotation,
NativeModuleParamTypeAnnotation,
NamedShape,
} from '../CodegenSchema';
import type {ParserType} from './errors';
import type {TypeAliasResolutionStatus} from './utils';
import type {
ParserErrorCapturer,
TypeAliasResolutionStatus,
TypeDeclarationMap,
} from './utils';

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

const {
throwIfUnsupportedFunctionParamTypeAnnotationParserError,
throwIfUnsupportedFunctionReturnTypeAnnotationParserError,
} = require('./error-utils');

const {
unwrapNullable,
wrapNullable,
assertGenericTypeAnnotationHasExactlyOneTypeParameter,
} = require('./parsers-commons');
Expand Down Expand Up @@ -190,6 +204,137 @@ function emitFloat(
});
}
function getTypeAnnotationParameters(
typeAnnotation: $FlowFixMe,
language: ParserType,
): $ReadOnlyArray<$FlowFixMe> {
return language === 'Flow'
? typeAnnotation.params
: typeAnnotation.parameters;
}
function getFunctionNameFromParameter(
param: NamedShape<Nullable<NativeModuleParamTypeAnnotation>>,
language: ParserType,
) {
return language === 'Flow' ? param.name : param.typeAnnotation;
}
function getParameterName(param: $FlowFixMe, language: ParserType): string {
return language === 'Flow' ? param.name.name : param.name;
}
function getParameterTypeAnnotation(param: $FlowFixMe, language: ParserType) {
return language === 'Flow'
? param.typeAnnotation
: param.typeAnnotation.typeAnnotation;
}
function getTypeAnnotationReturnType(
typeAnnotation: $FlowFixMe,
language: ParserType,
) {
return language === 'Flow'
? typeAnnotation.returnType
: typeAnnotation.typeAnnotation.typeAnnotation;
}
function translateFunctionTypeAnnotation(
hasteModuleName: string,
// TODO(T108222691): Use flow-types for @babel/parser
// TODO(T71778680): This is a FunctionTypeAnnotation. Type this.
typeAnnotation: $FlowFixMe,
types: TypeDeclarationMap,
aliasMap: {...NativeModuleAliasMap},
tryParse: ParserErrorCapturer,
cxxOnly: boolean,
translateTypeAnnotation: $FlowFixMe,
language: ParserType,
): NativeModuleFunctionTypeAnnotation {
type Param = NamedShape<Nullable<NativeModuleParamTypeAnnotation>>;
const params: Array<Param> = [];
for (const param of getTypeAnnotationParameters(typeAnnotation, language)) {
const parsedParam = tryParse(() => {
if (getFunctionNameFromParameter(param, language) == null) {
throw new UnnamedFunctionParamParserError(
param,
hasteModuleName,
language,
);
}
const paramName = getParameterName(param, language);
const [paramTypeAnnotation, isParamTypeAnnotationNullable] =
unwrapNullable(
translateTypeAnnotation(
hasteModuleName,
getParameterTypeAnnotation(param, language),
types,
aliasMap,
tryParse,
cxxOnly,
),
);
if (
paramTypeAnnotation.type === 'VoidTypeAnnotation' ||
paramTypeAnnotation.type === 'PromiseTypeAnnotation'
) {
return throwIfUnsupportedFunctionParamTypeAnnotationParserError(
hasteModuleName,
param.typeAnnotation,
paramName,
paramTypeAnnotation.type,
);
}

return {
name: paramName,
optional: Boolean(param.optional),
typeAnnotation: wrapNullable(
isParamTypeAnnotationNullable,
paramTypeAnnotation,
),
};
});

if (parsedParam != null) {
params.push(parsedParam);
}
}

const [returnTypeAnnotation, isReturnTypeAnnotationNullable] = unwrapNullable(
translateTypeAnnotation(
hasteModuleName,
getTypeAnnotationReturnType(typeAnnotation, language),
types,
aliasMap,
tryParse,
cxxOnly,
),
);

throwIfUnsupportedFunctionReturnTypeAnnotationParserError(
hasteModuleName,
typeAnnotation,
'FunctionTypeAnnotation',
language,
cxxOnly,
returnTypeAnnotation.type,
);

return {
type: 'FunctionTypeAnnotation',
returnTypeAnnotation: wrapNullable(
isReturnTypeAnnotationNullable,
returnTypeAnnotation,
),
params,
};
}

module.exports = {
emitBoolean,
emitDouble,
Expand All @@ -205,4 +350,5 @@ module.exports = {
emitStringish,
emitMixedTypeAnnotation,
typeAliasResolution,
translateFunctionTypeAnnotation,
};
Loading

0 comments on commit 62244d4

Please sign in to comment.