GenerateModuleJniCpp: Replace string replace with string templates

Summary:
## Benefits:
- Improved Readability
- Improved type-safety with templates

Changelog: [Internal]

Reviewed By: fkgozali

Differential Revision: D24386280

fbshipit-source-id: 9af78d8aabd86a6afb53660ff97d550973e5d11b
This commit is contained in:
Ramanpreet Nara 2020-10-19 21:56:26 -07:00 коммит произвёл Facebook GitHub Bot
Родитель 35ee7c8246
Коммит 5a73af684d
2 изменённых файлов: 120 добавлений и 91 удалений

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

@ -26,33 +26,78 @@ const {unwrapNullable} = require('../../parsers/flow/modules/utils');
type FilesOutput = Map<string, string>;
const propertyHeaderTemplate =
'static facebook::jsi::Value __hostFunction_::_HASTE_MODULE_NAME_::SpecJSI_::_PROPERTY_NAME_::(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {';
type JSReturnType =
| 'VoidKind'
| 'StringKind'
| 'BooleanKind'
| 'NumberKind'
| 'PromiseKind'
| 'ObjectKind'
| 'ArrayKind';
const propertyCastTemplate =
'static_cast<JavaTurboModule &>(turboModule).invokeJavaMethod(rt, ::_KIND_::, "::_PROPERTY_NAME_::", "::_SIGNATURE_::", args, count);';
const propertyTemplate = `
${propertyHeaderTemplate}
return ${propertyCastTemplate}
const HostFunctionTemplate = ({
hasteModuleName,
propertyName,
jniSignature,
jsReturnType,
}: $ReadOnly<{|
hasteModuleName: string,
propertyName: string,
jniSignature: string,
jsReturnType: JSReturnType,
|}>) => {
return `static facebook::jsi::Value __hostFunction_${hasteModuleName}SpecJSI_${propertyName}(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
return static_cast<JavaTurboModule &>(turboModule).invokeJavaMethod(rt, ${jsReturnType}, "${propertyName}", "${jniSignature}", args, count);
}`;
};
const propertyDefTemplate =
' methodMap_["::_PROPERTY_NAME_::"] = MethodMetadata {::_ARGS_COUNT_::, __hostFunction_::_HASTE_MODULE_NAME_::SpecJSI_::_PROPERTY_NAME_::};';
const moduleTemplate = `
::_TURBOMODULE_METHOD_INVOKERS_::
::_HASTE_MODULE_NAME_::SpecJSI::::_HASTE_MODULE_NAME_::SpecJSI(const JavaTurboModule::InitParams &params)
const ModuleClassConstructorTemplate = ({
hasteModuleName,
methods,
}: $ReadOnly<{|
hasteModuleName: string,
methods: $ReadOnlyArray<{|
propertyName: string,
argCount: number,
|}>,
|}>) => {
return `
${hasteModuleName}SpecJSI::${hasteModuleName}SpecJSI(const JavaTurboModule::InitParams &params)
: JavaTurboModule(params) {
::_PROPERTIES_MAP_::
${methods
.map(({propertyName, argCount}) => {
return ` methodMap_["${propertyName}"] = MethodMetadata {${argCount}, __hostFunction_${hasteModuleName}SpecJSI_${propertyName}};`;
})
.join('\n')}
}`.trim();
};
const oneModuleLookupTemplate = ` if (moduleName == "::_NATIVE_MODULE_NAME_::") {
return std::make_shared<::_HASTE_MODULE_NAME_::SpecJSI>(params);
const ModuleLookupTemplate = ({
moduleName,
hasteModuleName,
}: $ReadOnly<{|moduleName: string, hasteModuleName: string|}>) => {
return ` if (moduleName == "${moduleName}") {
return std::make_shared<${hasteModuleName}SpecJSI>(params);
}`;
};
const template = `
const FileTemplate = ({
libraryName,
include,
modules,
moduleLookups,
}: $ReadOnly<{|
libraryName: string,
include: string,
modules: string,
moduleLookups: $ReadOnlyArray<
$ReadOnly<{|
hasteModuleName: string,
moduleName: string,
|}>,
>,
|}>) => {
return `
/**
* ${'C'}opyright (c) Facebook, Inc. and its affiliates.
*
@ -62,26 +107,27 @@ const template = `
* ${'@'}generated by codegen project: GenerateModuleJniCpp.js
*/
#include ::_INCLUDE_::
#include ${include}
namespace facebook {
namespace react {
::_MODULES_::
${modules}
std::shared_ptr<TurboModule> ::_LIBRARY_NAME_::_ModuleProvider(const std::string moduleName, const JavaTurboModule::InitParams &params) {
::_MODULE_LOOKUP_::
std::shared_ptr<TurboModule> ${libraryName}_ModuleProvider(const std::string moduleName, const JavaTurboModule::InitParams &params) {
${moduleLookups.map(ModuleLookupTemplate).join('\n')}
return nullptr;
}
} // namespace react
} // namespace facebook
`;
};
function translateReturnTypeToKind(
nullableTypeAnnotation: Nullable<NativeModuleReturnTypeAnnotation>,
resolveAlias: AliasResolver,
): string {
): JSReturnType {
const [typeAnnotation] = unwrapNullable<NativeModuleReturnTypeAnnotation>(
nullableTypeAnnotation,
);
@ -278,6 +324,7 @@ function translateMethodTypeToJniSignature(
}
function translateMethodForImplementation(
hasteModuleName: string,
property: NativeModulePropertySchema,
resolveAlias: AliasResolver,
): string {
@ -288,41 +335,20 @@ function translateMethodForImplementation(
);
const {returnTypeAnnotation} = propertyTypeAnnotation;
const numberOfParams =
propertyTypeAnnotation.params.length +
(returnTypeAnnotation.type === 'PromiseTypeAnnotation' ? 1 : 0);
const translatedArguments = propertyTypeAnnotation.params
.map(param => param.name)
.concat(
returnTypeAnnotation.type === 'PromiseTypeAnnotation' ? ['promise'] : [],
)
.slice(1)
.join(':')
.concat(':');
if (
property.name === 'getConstants' &&
returnTypeAnnotation.type === 'ObjectTypeAnnotation' &&
returnTypeAnnotation.properties &&
returnTypeAnnotation.properties.length === 0
) {
return '';
}
return propertyTemplate
.replace(
/::_KIND_::/g,
translateReturnTypeToKind(returnTypeAnnotation, resolveAlias),
)
.replace(/::_PROPERTY_NAME_::/g, property.name)
.replace(
/::_ARGS_::/g,
numberOfParams === 0
? ''
: (numberOfParams === 1 ? '' : ':') + translatedArguments,
)
.replace(
/::_SIGNATURE_::/g,
translateMethodTypeToJniSignature(property, resolveAlias),
);
return HostFunctionTemplate({
hasteModuleName,
propertyName: property.name,
jniSignature: translateMethodTypeToJniSignature(property, resolveAlias),
jsReturnType: translateReturnTypeToKind(returnTypeAnnotation, resolveAlias),
});
}
module.exports = {
@ -351,14 +377,20 @@ module.exports = {
const translatedMethods = properties
.map(property =>
translateMethodForImplementation(property, resolveAlias),
translateMethodForImplementation(
hasteModuleName,
property,
resolveAlias,
),
)
.join('\n');
return moduleTemplate
.replace(/::_TURBOMODULE_METHOD_INVOKERS_::/g, translatedMethods)
.replace(
'::_PROPERTIES_MAP_::',
properties
.join('\n\n');
return (
translatedMethods +
'\n\n' +
ModuleClassConstructorTemplate({
hasteModuleName,
methods: properties
.map(({name: propertyName, typeAnnotation}) => {
const [
{returnTypeAnnotation, params},
@ -366,22 +398,27 @@ module.exports = {
typeAnnotation,
);
return propertyName === 'getConstants' &&
if (
propertyName === 'getConstants' &&
returnTypeAnnotation.type === 'ObjectTypeAnnotation' &&
returnTypeAnnotation.properties &&
returnTypeAnnotation.properties.length === 0
? ''
: propertyDefTemplate
.replace(/::_PROPERTY_NAME_::/g, propertyName)
.replace(/::_ARGS_COUNT_::/g, params.length.toString());
) {
return null;
}
return {
propertyName,
argCount: params.length,
};
})
.join('\n'),
)
.replace(/::_HASTE_MODULE_NAME_::/g, hasteModuleName);
.filter(Boolean),
})
);
})
.join('\n');
const moduleLookup = Object.keys(nativeModules)
const moduleLookups = Object.keys(nativeModules)
.filter(hasteModuleName => {
const module = nativeModules[hasteModuleName];
return !(
@ -401,24 +438,23 @@ module.exports = {
}
return 0;
})
.map(hasteModuleName => {
const {moduleNames} = nativeModules[hasteModuleName];
return moduleNames
.map(nativeModuleName =>
oneModuleLookupTemplate
.replace(/::_NATIVE_MODULE_NAME_::/g, nativeModuleName)
.replace(/::_HASTE_MODULE_NAME_::/g, hasteModuleName),
)
.join('\n');
})
.join('\n');
.flatMap<{|moduleName: string, hasteModuleName: string|}>(
(hasteModuleName: string) => {
const {moduleNames} = nativeModules[hasteModuleName];
return moduleNames.map(moduleName => ({
moduleName,
hasteModuleName,
}));
},
);
const fileName = `${moduleSpecName}-generated.cpp`;
const replacedTemplate = template
.replace(/::_MODULES_::/g, modules)
.replace(/::_LIBRARY_NAME_::/g, libraryName)
.replace(/::_MODULE_LOOKUP_::/g, moduleLookup)
.replace(/::_INCLUDE_::/g, `"${moduleSpecName}.h"`);
const replacedTemplate = FileTemplate({
modules: modules,
libraryName,
moduleLookups,
include: `"${moduleSpecName}.h"`,
});
return new Map([[fileName, replacedTemplate]]);
},
};

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

@ -17,7 +17,6 @@ Map {
namespace facebook {
namespace react {
static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_difficult(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
return static_cast<JavaTurboModule &>(turboModule).invokeJavaMethod(rt, ObjectKind, \\"difficult\\", \\"(Lcom/facebook/react/bridge/ReadableMap;)Lcom/facebook/react/bridge/WritableMap;\\", args, count);
}
@ -117,7 +116,6 @@ static facebook::jsi::Value __hostFunction_AliasTurboModuleSpecJSI_cropImage(fac
AliasTurboModuleSpecJSI::AliasTurboModuleSpecJSI(const JavaTurboModule::InitParams &params)
: JavaTurboModule(params) {
methodMap_[\\"cropImage\\"] = MethodMetadata {1, __hostFunction_AliasTurboModuleSpecJSI_cropImage};
}
@ -167,12 +165,10 @@ static facebook::jsi::Value __hostFunction_NativeCameraRollManagerSpecJSI_delete
NativeCameraRollManagerSpecJSI::NativeCameraRollManagerSpecJSI(const JavaTurboModule::InitParams &params)
: JavaTurboModule(params) {
methodMap_[\\"getPhotos\\"] = MethodMetadata {1, __hostFunction_NativeCameraRollManagerSpecJSI_getPhotos};
methodMap_[\\"saveToCameraRoll\\"] = MethodMetadata {2, __hostFunction_NativeCameraRollManagerSpecJSI_saveToCameraRoll};
methodMap_[\\"deletePhotos\\"] = MethodMetadata {1, __hostFunction_NativeCameraRollManagerSpecJSI_deletePhotos};
}
static facebook::jsi::Value __hostFunction_NativeExceptionsManagerSpecJSI_reportFatalException(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
return static_cast<JavaTurboModule &>(turboModule).invokeJavaMethod(rt, VoidKind, \\"reportFatalException\\", \\"(Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;D)V\\", args, count);
}
@ -235,7 +231,6 @@ Map {
namespace facebook {
namespace react {
static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
return static_cast<JavaTurboModule &>(turboModule).invokeJavaMethod(rt, ObjectKind, \\"getConstants\\", \\"()Ljava/util/Map;\\", args, count);
}
@ -325,7 +320,6 @@ Map {
namespace facebook {
namespace react {
static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
return static_cast<JavaTurboModule &>(turboModule).invokeJavaMethod(rt, VoidKind, \\"voidFunc\\", \\"()V\\", args, count);
}
@ -342,7 +336,6 @@ static facebook::jsi::Value __hostFunction_NativeSampleTurboModule2SpecJSI_voidF
NativeSampleTurboModule2SpecJSI::NativeSampleTurboModule2SpecJSI(const JavaTurboModule::InitParams &params)
: JavaTurboModule(params) {
methodMap_[\\"voidFunc\\"] = MethodMetadata {0, __hostFunction_NativeSampleTurboModule2SpecJSI_voidFunc};
}