mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Add generating Cpp from schema json
Summary: Add generating cpp files following NativeModuleSpec. We still need to figure out how to deal with module names, so I currently made in workable by extracting `Sample` from `SampleNativeModule` and filing into proper places, but it's a temporary solution. Reviewed By: rickhanlonii Differential Revision: D16181292 fbshipit-source-id: 0f50352d7610f99f0228045ae78309383d3e8bfa
This commit is contained in:
committed by
Facebook Github Bot
parent
859deb97f6
commit
2bc6e28d17
@@ -14,6 +14,35 @@ import type {SchemaType} from '../CodegenSchema';
|
||||
|
||||
type FilesOutput = Map<string, string>;
|
||||
|
||||
const propertyHeaderTemplate =
|
||||
'static jsi::Value __hostFunction_Native::_MODULE_NAME_::TurboCxxModuleSpecJSI_::_PROPERTY_NAME_::(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {';
|
||||
|
||||
const propertyCastTemplate =
|
||||
'static_cast<Native::_MODULE_NAME_::TurboCxxModuleSpecJSI *>(&turboModule)->::_PROPERTY_NAME_::(rt::_ARGS_::);';
|
||||
|
||||
const nonvoidPropertyTemplate = `
|
||||
${propertyHeaderTemplate}
|
||||
return ${propertyCastTemplate}
|
||||
}`;
|
||||
|
||||
const voidPropertyTemplate = `
|
||||
${propertyHeaderTemplate}
|
||||
${propertyCastTemplate}
|
||||
return jsi::Value::undefined();
|
||||
}`;
|
||||
|
||||
const proprertyDefTemplate =
|
||||
' methodMap_["::_PROPERTY_NAME_::"] = MethodMetadata {::_ARGS_COUNT_::, __hostFunction_Native::_MODULE_NAME_::TurboCxxModuleSpecJSI_::_PROPERTY_NAME_::};';
|
||||
|
||||
const moduleTemplate = `
|
||||
::_MODULE_PROPERTIES_::
|
||||
|
||||
Native::_MODULE_NAME_::TurboCxxModuleSpecJSI::Native::_MODULE_NAME_::TurboCxxModuleSpecJSI(std::shared_ptr<JSCallInvoker> jsInvoker)
|
||||
: TurboModule("::_MODULE_NAME_::TurboCxxModule", jsInvoker) {
|
||||
::_PROPERTIES_MAP_::
|
||||
}
|
||||
`;
|
||||
|
||||
const template = `
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
@@ -27,23 +56,94 @@ const template = `
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
::_MODULE_PROPERTIES_::
|
||||
::_PROPERTIES_MAP_::
|
||||
::_MODULES_::
|
||||
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
`;
|
||||
|
||||
function traverseArg(arg, index): string {
|
||||
function wrap(suffix) {
|
||||
return `args[${index}]${suffix}`;
|
||||
}
|
||||
const type = arg.typeAnnotation.type;
|
||||
switch (type) {
|
||||
case 'StringTypeAnnotation':
|
||||
return wrap('.getString(rt)');
|
||||
case 'BooleanTypeAnnotation':
|
||||
return wrap('.getBool(rt)');
|
||||
case 'NumberTypeAnnotation':
|
||||
case 'FloatTypeAnnotation':
|
||||
case 'Int32TypeAnnotation':
|
||||
return wrap('.getNumber(rt)');
|
||||
case 'ArrayTypeAnnotation':
|
||||
return wrap('.getObject(rt).getArray(rt)');
|
||||
case 'FunctionTypeAnnotation':
|
||||
return `std::move(${wrap('.getObject(rt).getFunction(rt)')})`;
|
||||
case 'GenericObjectTypeAnnotation':
|
||||
case 'ObjectTypeAnnotation':
|
||||
return wrap('.getObject(rt)');
|
||||
case 'AnyTypeAnnotation':
|
||||
throw new Error(`Any type is not allowed in params for "${arg.name}"`);
|
||||
|
||||
default:
|
||||
(type: empty);
|
||||
throw new Error(`Unknown prop type for "${arg.name}, found: ${type}"`);
|
||||
}
|
||||
}
|
||||
|
||||
function traverseProprety(property): string {
|
||||
const propertyTemplate =
|
||||
property.typeAnnotation.returnTypeAnnotation.type === 'VoidTypeAnnotation'
|
||||
? voidPropertyTemplate
|
||||
: nonvoidPropertyTemplate;
|
||||
const traversedArgs = property.typeAnnotation.params
|
||||
.map(traverseArg)
|
||||
.join(', ');
|
||||
return propertyTemplate
|
||||
.replace(/::_PROPERTY_NAME_::/g, property.name)
|
||||
.replace(/::_ARGS_::/g, traversedArgs === '' ? '' : ', ' + traversedArgs);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
generate(libraryName: string, schema: SchemaType): FilesOutput {
|
||||
const fileName = `${libraryName}.cpp`;
|
||||
const nativeModules = Object.keys(schema.modules)
|
||||
.map(moduleName => {
|
||||
const modules = schema.modules[moduleName].nativeModules;
|
||||
if (modules == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const moduleProperties = '';
|
||||
return modules;
|
||||
})
|
||||
.filter(Boolean)
|
||||
.reduce((acc, modules) => Object.assign(acc, modules), {});
|
||||
|
||||
const replacedTemplate = template
|
||||
.replace(/::_MODULE_PROPERTIES_::/g, moduleProperties)
|
||||
.replace('::_MODULE_NAME_::', libraryName)
|
||||
.replace('::_PROPERTIES_MAP_::', '');
|
||||
const modules = Object.keys(nativeModules)
|
||||
.map(name => {
|
||||
const {properties} = nativeModules[name];
|
||||
const traversedProperties = properties
|
||||
.map(property => traverseProprety(property))
|
||||
.join('\n');
|
||||
return moduleTemplate
|
||||
.replace(/::_MODULE_PROPERTIES_::/g, traversedProperties)
|
||||
.replace(
|
||||
'::_PROPERTIES_MAP_::',
|
||||
properties
|
||||
.map(({name: propertyName, typeAnnotation: {params}}) =>
|
||||
proprertyDefTemplate
|
||||
.replace(/::_PROPERTY_NAME_::/g, propertyName)
|
||||
.replace(/::_ARGS_COUNT_::/g, params.length.toString()),
|
||||
)
|
||||
.join('\n'),
|
||||
)
|
||||
.replace(/::_MODULE_NAME_::/g, name.slice(0, -11)); // FIXME
|
||||
})
|
||||
.join('\n');
|
||||
|
||||
const fileName = 'NativeModules.h';
|
||||
const replacedTemplate = template.replace(/::_MODULES_::/g, modules);
|
||||
|
||||
return new Map([[fileName, replacedTemplate]]);
|
||||
},
|
||||
|
||||
+68
-4
@@ -2,7 +2,7 @@
|
||||
|
||||
exports[`GenerateModuleCpp can generate fixture EMPTY_NATIVE_MODULES 1`] = `
|
||||
Map {
|
||||
"EMPTY_NATIVE_MODULES.cpp" => "
|
||||
"NativeModules.h" => "
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
@@ -10,12 +10,19 @@ Map {
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include \\"NativeEMPTY_NATIVE_MODULESTurboCxxModuleSpecJSI.h\\"
|
||||
#include \\"Native::_MODULE_NAME_::TurboCxxModuleSpecJSI.h\\"
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
|
||||
|
||||
|
||||
NativeSampleTurboCxxModuleSpecJSI::NativeSampleTurboCxxModuleSpecJSI(std::shared_ptr<JSCallInvoker> jsInvoker)
|
||||
: TurboModule(\\"SampleTurboCxxModule\\", jsInvoker) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace react
|
||||
@@ -26,7 +33,7 @@ namespace react {
|
||||
|
||||
exports[`GenerateModuleCpp can generate fixture SIMPLE_NATIVE_MODULES 1`] = `
|
||||
Map {
|
||||
"SIMPLE_NATIVE_MODULES.cpp" => "
|
||||
"NativeModules.h" => "
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
@@ -34,13 +41,70 @@ Map {
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include \\"NativeSIMPLE_NATIVE_MODULESTurboCxxModuleSpecJSI.h\\"
|
||||
#include \\"Native::_MODULE_NAME_::TurboCxxModuleSpecJSI.h\\"
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
|
||||
|
||||
static jsi::Value __hostFunction_NativeSampleTurboCxxModuleSpecJSI_getConstants(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
|
||||
return static_cast<NativeSampleTurboCxxModuleSpecJSI *>(&turboModule)->getConstants(rt);
|
||||
}
|
||||
|
||||
static jsi::Value __hostFunction_NativeSampleTurboCxxModuleSpecJSI_voidFunc(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
|
||||
static_cast<NativeSampleTurboCxxModuleSpecJSI *>(&turboModule)->voidFunc(rt);
|
||||
return jsi::Value::undefined();
|
||||
}
|
||||
|
||||
static jsi::Value __hostFunction_NativeSampleTurboCxxModuleSpecJSI_getBool(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
|
||||
return static_cast<NativeSampleTurboCxxModuleSpecJSI *>(&turboModule)->getBool(rt, args[0].getBool(rt));
|
||||
}
|
||||
|
||||
static jsi::Value __hostFunction_NativeSampleTurboCxxModuleSpecJSI_getNumber(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
|
||||
return static_cast<NativeSampleTurboCxxModuleSpecJSI *>(&turboModule)->getNumber(rt, args[0].getNumber(rt));
|
||||
}
|
||||
|
||||
static jsi::Value __hostFunction_NativeSampleTurboCxxModuleSpecJSI_getString(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
|
||||
return static_cast<NativeSampleTurboCxxModuleSpecJSI *>(&turboModule)->getString(rt, args[0].getString(rt));
|
||||
}
|
||||
|
||||
static jsi::Value __hostFunction_NativeSampleTurboCxxModuleSpecJSI_getArray(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
|
||||
return static_cast<NativeSampleTurboCxxModuleSpecJSI *>(&turboModule)->getArray(rt, args[0].getObject(rt).getArray(rt));
|
||||
}
|
||||
|
||||
static jsi::Value __hostFunction_NativeSampleTurboCxxModuleSpecJSI_getObject(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
|
||||
return static_cast<NativeSampleTurboCxxModuleSpecJSI *>(&turboModule)->getObject(rt, args[0].getObject(rt));
|
||||
}
|
||||
|
||||
static jsi::Value __hostFunction_NativeSampleTurboCxxModuleSpecJSI_getValue(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
|
||||
return static_cast<NativeSampleTurboCxxModuleSpecJSI *>(&turboModule)->getValue(rt, args[0].getNumber(rt), args[1].getString(rt), args[2].getObject(rt));
|
||||
}
|
||||
|
||||
static jsi::Value __hostFunction_NativeSampleTurboCxxModuleSpecJSI_getValueWithCallback(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
|
||||
static_cast<NativeSampleTurboCxxModuleSpecJSI *>(&turboModule)->getValueWithCallback(rt, std::move(args[0].getObject(rt).getFunction(rt)));
|
||||
return jsi::Value::undefined();
|
||||
}
|
||||
|
||||
static jsi::Value __hostFunction_NativeSampleTurboCxxModuleSpecJSI_getValueWithPromise(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
|
||||
return static_cast<NativeSampleTurboCxxModuleSpecJSI *>(&turboModule)->getValueWithPromise(rt, args[0].getBool(rt));
|
||||
}
|
||||
|
||||
NativeSampleTurboCxxModuleSpecJSI::NativeSampleTurboCxxModuleSpecJSI(std::shared_ptr<JSCallInvoker> jsInvoker)
|
||||
: TurboModule(\\"SampleTurboCxxModule\\", jsInvoker) {
|
||||
methodMap_[\\"getConstants\\"] = MethodMetadata {0, __hostFunction_NativeSampleTurboCxxModuleSpecJSI_getConstants};
|
||||
methodMap_[\\"voidFunc\\"] = MethodMetadata {0, __hostFunction_NativeSampleTurboCxxModuleSpecJSI_voidFunc};
|
||||
methodMap_[\\"getBool\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboCxxModuleSpecJSI_getBool};
|
||||
methodMap_[\\"getNumber\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboCxxModuleSpecJSI_getNumber};
|
||||
methodMap_[\\"getString\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboCxxModuleSpecJSI_getString};
|
||||
methodMap_[\\"getArray\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboCxxModuleSpecJSI_getArray};
|
||||
methodMap_[\\"getObject\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboCxxModuleSpecJSI_getObject};
|
||||
methodMap_[\\"getValue\\"] = MethodMetadata {3, __hostFunction_NativeSampleTurboCxxModuleSpecJSI_getValue};
|
||||
methodMap_[\\"getValueWithCallback\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboCxxModuleSpecJSI_getValueWithCallback};
|
||||
methodMap_[\\"getValueWithPromise\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboCxxModuleSpecJSI_getValueWithPromise};
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
|
||||
Reference in New Issue
Block a user