Search
Search
Search
Search
Information
Information
Light
Dark
Open actions menu
Basic upload method
Bypass upload method
Tips!
If you encounter an error (by firewall) while uploading using both methods,
try changing extension of the file before uploading it and rename it right after.
This uploader supports multiple file upload.
Submit
~
var
www
uibuilder.cmshelp.dk
httpdocs
node_modules
@react-native
codegen
lib
generators
modules
File Content:
GenerateModuleH.js.flow
/** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @flow strict * @format */ 'use strict'; import type { NamedShape, NativeModuleBaseTypeAnnotation, } from '../../CodegenSchema'; import type { NativeModuleAliasMap, NativeModuleEnumMap, NativeModuleEnumMember, NativeModuleEnumMemberType, NativeModuleEventEmitterShape, NativeModuleFunctionTypeAnnotation, NativeModulePropertyShape, NativeModuleTypeAnnotation, Nullable, SchemaType, } from '../../CodegenSchema'; import type {AliasResolver} from './Utils'; const {unwrapNullable} = require('../../parsers/parsers-commons'); const {wrapOptional} = require('../TypeUtils/Cxx'); const {getEnumName, toPascalCase, toSafeCppString} = require('../Utils'); const {indent} = require('../Utils'); const { createAliasResolver, getModules, isArrayRecursiveMember, isDirectRecursiveMember, } = require('./Utils'); type FilesOutput = Map<string, string>; const ModuleClassDeclarationTemplate = ({ hasteModuleName, moduleProperties, structs, enums, }: $ReadOnly<{ hasteModuleName: string, moduleProperties: string[], structs: string, enums: string, }>) => { return `${enums} ${structs}class JSI_EXPORT ${hasteModuleName}CxxSpecJSI : public TurboModule { protected: ${hasteModuleName}CxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker); public: ${indent(moduleProperties.join('\n'), 2)} };`; }; const ModuleSpecClassDeclarationTemplate = ({ hasteModuleName, moduleName, moduleEventEmitters, moduleProperties, }: $ReadOnly<{ hasteModuleName: string, moduleName: string, moduleEventEmitters: EventEmitterCpp[], moduleProperties: string[], }>) => { return `template <typename T> class JSI_EXPORT ${hasteModuleName}CxxSpec : public TurboModule { public: jsi::Value create(jsi::Runtime &rt, const jsi::PropNameID &propName) override { return delegate_.create(rt, propName); } std::vector<jsi::PropNameID> getPropertyNames(jsi::Runtime& runtime) override { return delegate_.getPropertyNames(runtime); } static constexpr std::string_view kModuleName = "${moduleName}"; protected: ${hasteModuleName}CxxSpec(std::shared_ptr<CallInvoker> jsInvoker) : TurboModule(std::string{${hasteModuleName}CxxSpec::kModuleName}, jsInvoker), delegate_(reinterpret_cast<T*>(this), jsInvoker) {} ${moduleEventEmitters.map(e => e.emitFunction).join('\n')} private: class Delegate : public ${hasteModuleName}CxxSpecJSI { public: Delegate(T *instance, std::shared_ptr<CallInvoker> jsInvoker) : ${hasteModuleName}CxxSpecJSI(std::move(jsInvoker)), instance_(instance) { ${moduleEventEmitters.map(e => e.registerEventEmitter).join('\n')} } ${indent(moduleProperties.join('\n'), 4)} private: friend class ${hasteModuleName}CxxSpec; T *instance_; }; Delegate delegate_; };`; }; const FileTemplate = ({ modules, }: $ReadOnly<{ modules: string[], }>) => { return `/** * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). * * Do not edit this file as changes may cause incorrect behavior and will be lost * once the code is regenerated. * * ${'@'}generated by codegen project: GenerateModuleH.js */ #pragma once #include <ReactCommon/TurboModule.h> #include <react/bridging/Bridging.h> namespace facebook::react { ${modules.join('\n\n')} } // namespace facebook::react `; }; function translatePrimitiveJSTypeToCpp( moduleName: string, parentObjectAliasName: ?string, nullableTypeAnnotation: Nullable<NativeModuleTypeAnnotation>, optional: boolean, createErrorMessage: (typeName: string) => string, resolveAlias: AliasResolver, enumMap: NativeModuleEnumMap, ) { const [typeAnnotation, nullable] = unwrapNullable<NativeModuleTypeAnnotation>( nullableTypeAnnotation, ); const isRecursiveType = isDirectRecursiveMember( parentObjectAliasName, nullableTypeAnnotation, ); const isRequired = (!optional && !nullable) || isRecursiveType; let realTypeAnnotation = typeAnnotation; if (realTypeAnnotation.type === 'TypeAliasTypeAnnotation') { realTypeAnnotation = resolveAlias(realTypeAnnotation.name); } switch (realTypeAnnotation.type) { case 'ReservedTypeAnnotation': switch (realTypeAnnotation.name) { case 'RootTag': return wrapOptional('double', isRequired); default: (realTypeAnnotation.name: empty); throw new Error(createErrorMessage(realTypeAnnotation.name)); } case 'VoidTypeAnnotation': return 'void'; case 'StringTypeAnnotation': return wrapOptional('jsi::String', isRequired); case 'StringLiteralTypeAnnotation': return wrapOptional('jsi::String', isRequired); case 'StringLiteralUnionTypeAnnotation': return wrapOptional('jsi::String', isRequired); case 'NumberTypeAnnotation': return wrapOptional('double', isRequired); case 'NumberLiteralTypeAnnotation': return wrapOptional('double', isRequired); case 'DoubleTypeAnnotation': return wrapOptional('double', isRequired); case 'FloatTypeAnnotation': return wrapOptional('double', isRequired); case 'Int32TypeAnnotation': return wrapOptional('int', isRequired); case 'BooleanTypeAnnotation': return wrapOptional('bool', isRequired); case 'EnumDeclaration': switch (realTypeAnnotation.memberType) { case 'NumberTypeAnnotation': return wrapOptional('jsi::Value', isRequired); case 'StringTypeAnnotation': return wrapOptional('jsi::String', isRequired); default: throw new Error(createErrorMessage(realTypeAnnotation.type)); } case 'GenericObjectTypeAnnotation': return wrapOptional('jsi::Object', isRequired); case 'UnionTypeAnnotation': switch (typeAnnotation.memberType) { case 'NumberTypeAnnotation': return wrapOptional('double', isRequired); case 'ObjectTypeAnnotation': return wrapOptional('jsi::Object', isRequired); case 'StringTypeAnnotation': return wrapOptional('jsi::String', isRequired); default: throw new Error(createErrorMessage(realTypeAnnotation.type)); } case 'ObjectTypeAnnotation': return wrapOptional('jsi::Object', isRequired); case 'ArrayTypeAnnotation': return wrapOptional('jsi::Array', isRequired); case 'FunctionTypeAnnotation': return wrapOptional('jsi::Function', isRequired); case 'PromiseTypeAnnotation': return wrapOptional('jsi::Value', isRequired); case 'MixedTypeAnnotation': return wrapOptional('jsi::Value', isRequired); default: (realTypeAnnotation.type: empty); throw new Error(createErrorMessage(realTypeAnnotation.type)); } } function createStructsString( hasteModuleName: string, aliasMap: NativeModuleAliasMap, resolveAlias: AliasResolver, enumMap: NativeModuleEnumMap, ): string { const getCppType = ( parentObjectAlias: string, v: NamedShape<Nullable<NativeModuleBaseTypeAnnotation>>, ) => translatePrimitiveJSTypeToCpp( hasteModuleName, parentObjectAlias, v.typeAnnotation, false, typeName => `Unsupported type for param "${v.name}". Found: ${typeName}`, resolveAlias, enumMap, ); return Object.keys(aliasMap) .map(alias => { const value = aliasMap[alias]; if (value.properties.length === 0) { return ''; } const structName = `${hasteModuleName}${alias}`; const templateParameter = value.properties.filter( v => !isDirectRecursiveMember(alias, v.typeAnnotation) && !isArrayRecursiveMember(alias, v.typeAnnotation), ); const templateParameterWithTypename = templateParameter .map((v, i) => `typename P${i}`) .join(', '); const templateParameterWithoutTypename = templateParameter .map((v, i) => `P${i}`) .join(', '); let i = -1; const templateMemberTypes = value.properties.map(v => { if (isDirectRecursiveMember(alias, v.typeAnnotation)) { return `std::unique_ptr<${structName}<${templateParameterWithoutTypename}>> ${v.name}`; } else if (isArrayRecursiveMember(alias, v.typeAnnotation)) { const [nullable] = unwrapNullable<NativeModuleTypeAnnotation>( v.typeAnnotation, ); return ( (nullable ? `std::optional<std::vector<${structName}<${templateParameterWithoutTypename}>>>` : `std::vector<${structName}<${templateParameterWithoutTypename}>>`) + ` ${v.name}` ); } else { i++; return `P${i} ${v.name}`; } }); const debugParameterConversion = value.properties .map( v => ` static ${getCppType(alias, v)} ${ v.name }ToJs(jsi::Runtime &rt, decltype(types.${v.name}) value) { return bridging::toJs(rt, value); }`, ) .join('\n\n'); return ` #pragma mark - ${structName} template <${templateParameterWithTypename}> struct ${structName} { ${templateMemberTypes.map(v => ' ' + v).join(';\n')}; bool operator==(const ${structName} &other) const { return ${value.properties .map(v => `${v.name} == other.${v.name}`) .join(' && ')}; } }; template <typename T> struct ${structName}Bridging { static T types; static T fromJs( jsi::Runtime &rt, const jsi::Object &value, const std::shared_ptr<CallInvoker> &jsInvoker) { T result{ ${value.properties .map(v => { if (isDirectRecursiveMember(alias, v.typeAnnotation)) { return ` value.hasProperty(rt, "${v.name}") ? std::make_unique<T>(bridging::fromJs<T>(rt, value.getProperty(rt, "${v.name}"), jsInvoker)) : nullptr`; } else { return ` bridging::fromJs<decltype(types.${v.name})>(rt, value.getProperty(rt, "${v.name}"), jsInvoker)`; } }) .join(',\n')}}; return result; } #ifdef DEBUG ${debugParameterConversion} #endif static jsi::Object toJs( jsi::Runtime &rt, const T &value, const std::shared_ptr<CallInvoker> &jsInvoker) { auto result = facebook::jsi::Object(rt); ${value.properties .map(v => { if (isDirectRecursiveMember(alias, v.typeAnnotation)) { return ` if (value.${v.name}) { result.setProperty(rt, "${v.name}", bridging::toJs(rt, *value.${v.name}, jsInvoker)); }`; } else if (v.optional) { return ` if (value.${v.name}) { result.setProperty(rt, "${v.name}", bridging::toJs(rt, value.${v.name}.value(), jsInvoker)); }`; } else { return ` result.setProperty(rt, "${v.name}", bridging::toJs(rt, value.${v.name}, jsInvoker));`; } }) .join('\n')} return result; } }; `; }) .join('\n'); } type NativeEnumMemberValueType = 'std::string' | 'int32_t'; const EnumTemplate = ({ enumName, values, fromCases, toCases, nativeEnumMemberType, }: { enumName: string, values: string, fromCases: string, toCases: string, nativeEnumMemberType: NativeEnumMemberValueType, }) => { const [fromValue, fromValueConversion, toValue] = nativeEnumMemberType === 'std::string' ? [ 'const jsi::String &rawValue', 'std::string value = rawValue.utf8(rt);', 'jsi::String', ] : [ 'const jsi::Value &rawValue', 'double value = (double)rawValue.asNumber();', 'jsi::Value', ]; return ` #pragma mark - ${enumName} enum class ${enumName} { ${values} }; template <> struct Bridging<${enumName}> { static ${enumName} fromJs(jsi::Runtime &rt, ${fromValue}) { ${fromValueConversion} ${fromCases} } static ${toValue} toJs(jsi::Runtime &rt, ${enumName} value) { ${toCases} } };`; }; function getMemberValueAppearance(member: NativeModuleEnumMember['value']) { if (member.type === 'StringLiteralTypeAnnotation') { return `"${member.value}"`; } else { return member.value; } } function generateEnum( hasteModuleName: string, origEnumName: string, members: $ReadOnlyArray<NativeModuleEnumMember>, memberType: NativeModuleEnumMemberType, ): string { const enumName = getEnumName(hasteModuleName, origEnumName); const nativeEnumMemberType: NativeEnumMemberValueType = memberType === 'StringTypeAnnotation' ? 'std::string' : 'int32_t'; const fromCases = members .map( member => `if (value == ${getMemberValueAppearance(member.value)}) { return ${enumName}::${toSafeCppString(member.name)}; }`, ) .join(' else ') + ` else { throw jsi::JSError(rt, "No appropriate enum member found for value"); }`; const toCases = members .map( member => `if (value == ${enumName}::${toSafeCppString(member.name)}) { return bridging::toJs(rt, ${getMemberValueAppearance(member.value)}); }`, ) .join(' else ') + ` else { throw jsi::JSError(rt, "No appropriate enum member found for enum value"); }`; return EnumTemplate({ enumName, values: members.map(member => toSafeCppString(member.name)).join(', '), fromCases, toCases, nativeEnumMemberType, }); } function createEnums( hasteModuleName: string, enumMap: NativeModuleEnumMap, resolveAlias: AliasResolver, ): string { return Object.entries(enumMap) .map(([enumName, enumNode]) => { return generateEnum( hasteModuleName, enumName, enumNode.members, enumNode.memberType, ); }) .filter(Boolean) .join('\n'); } function translatePropertyToCpp( hasteModuleName: string, prop: NativeModulePropertyShape, resolveAlias: AliasResolver, enumMap: NativeModuleEnumMap, abstract: boolean = false, ): string { const [propTypeAnnotation] = unwrapNullable<NativeModuleFunctionTypeAnnotation>(prop.typeAnnotation); const params = propTypeAnnotation.params.map( param => `std::move(${param.name})`, ); const paramTypes = propTypeAnnotation.params.map(param => { const translatedParam = translatePrimitiveJSTypeToCpp( hasteModuleName, null, param.typeAnnotation, param.optional, typeName => `Unsupported type for param "${param.name}" in ${prop.name}. Found: ${typeName}`, resolveAlias, enumMap, ); return `${translatedParam} ${param.name}`; }); const returnType = translatePrimitiveJSTypeToCpp( hasteModuleName, null, propTypeAnnotation.returnTypeAnnotation, false, typeName => `Unsupported return type for ${prop.name}. Found: ${typeName}`, resolveAlias, enumMap, ); // The first param will always be the runtime reference. paramTypes.unshift('jsi::Runtime &rt'); const method = `${returnType} ${prop.name}(${paramTypes.join(', ')})`; if (abstract) { return `virtual ${method} = 0;`; } return `${method} override { static_assert( bridging::getParameterCount(&T::${prop.name}) == ${paramTypes.length}, "Expected ${prop.name}(...) to have ${paramTypes.length} parameters"); return bridging::callFromJs<${returnType}>( rt, &T::${prop.name}, jsInvoker_, ${['instance_', ...params].join(', ')}); }`; } type EventEmitterCpp = { isVoidTypeAnnotation: boolean, templateName: string, registerEventEmitter: string, emitFunction: string, }; function translateEventEmitterToCpp( moduleName: string, eventEmitter: NativeModuleEventEmitterShape, resolveAlias: AliasResolver, enumMap: NativeModuleEnumMap, ): EventEmitterCpp { const isVoidTypeAnnotation = eventEmitter.typeAnnotation.typeAnnotation.type === 'VoidTypeAnnotation'; const templateName = `${toPascalCase(eventEmitter.name)}Type`; const jsiType = translatePrimitiveJSTypeToCpp( moduleName, null, eventEmitter.typeAnnotation.typeAnnotation, false, typeName => `Unsupported type for eventEmitter "${eventEmitter.name}" in ${moduleName}. Found: ${typeName}`, resolveAlias, enumMap, ); const isArray = jsiType === 'jsi::Array'; return { isVoidTypeAnnotation: isVoidTypeAnnotation, templateName: isVoidTypeAnnotation ? `/*${templateName}*/` : templateName, registerEventEmitter: ` eventEmitterMap_["${ eventEmitter.name }"] = std::make_shared<AsyncEventEmitter<${ isVoidTypeAnnotation ? '' : 'jsi::Value' }>>();`, emitFunction: ` ${ isVoidTypeAnnotation ? '' : `template <typename ${templateName}> ` }void emit${toPascalCase(eventEmitter.name)}(${ isVoidTypeAnnotation ? '' : `${isArray ? `std::vector<${templateName}>` : templateName} value` }) {${ isVoidTypeAnnotation ? '' : ` static_assert(bridging::supportsFromJs<${ isArray ? `std::vector<${templateName}>` : templateName }, ${jsiType}>, "value cannnot be converted to ${jsiType}");` } static_cast<AsyncEventEmitter<${ isVoidTypeAnnotation ? '' : 'jsi::Value' }>&>(*delegate_.eventEmitterMap_["${eventEmitter.name}"]).emit(${ isVoidTypeAnnotation ? '' : `[jsInvoker = jsInvoker_, eventValue = value](jsi::Runtime& rt) -> jsi::Value { return bridging::toJs(rt, eventValue, jsInvoker); }` }); }`, }; } module.exports = { generate( libraryName: string, schema: SchemaType, packageName?: string, assumeNonnull: boolean = false, headerPrefix?: string, ): FilesOutput { const nativeModules = getModules(schema); const modules = Object.keys(nativeModules).flatMap(hasteModuleName => { const {aliasMap, enumMap, spec, moduleName} = nativeModules[hasteModuleName]; const resolveAlias = createAliasResolver(aliasMap); const structs = createStructsString( hasteModuleName, aliasMap, resolveAlias, enumMap, ); const enums = createEnums(hasteModuleName, enumMap, resolveAlias); return [ ModuleClassDeclarationTemplate({ hasteModuleName, moduleProperties: spec.methods.map(prop => translatePropertyToCpp( hasteModuleName, prop, resolveAlias, enumMap, true, ), ), structs, enums, }), ModuleSpecClassDeclarationTemplate({ hasteModuleName, moduleName, moduleEventEmitters: spec.eventEmitters.map(eventEmitter => translateEventEmitterToCpp( moduleName, eventEmitter, resolveAlias, enumMap, ), ), moduleProperties: spec.methods.map(prop => translatePropertyToCpp( hasteModuleName, prop, resolveAlias, enumMap, ), ), }), ]; }); const fileName = `${libraryName}JSI.h`; const replacedTemplate = FileTemplate({modules}); return new Map([[fileName, replacedTemplate]]); }, };
Edit
Download
Unzip
Chmod
Delete