diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleCpp.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleCpp.js index c87add8b58c..365fd30a552 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleCpp.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleCpp.js @@ -11,7 +11,7 @@ 'use strict'; import type {SchemaType} from '../../CodegenSchema'; - +const {getTypeAliasTypeAnnotation} = require('./ObjCppUtils/Utils'); type FilesOutput = Map; const propertyHeaderTemplate = @@ -62,20 +62,25 @@ namespace react { } // namespace facebook `; -function traverseArg(arg, index): string { +function traverseArg(arg, index, aliases): string { function wrap(suffix) { return `args[${index}]${suffix}`; } const {typeAnnotation} = arg; - switch (typeAnnotation.type) { + + const realTypeAnnotation = + typeAnnotation.type === 'TypeAliasTypeAnnotation' + ? getTypeAliasTypeAnnotation(typeAnnotation.name, aliases) + : typeAnnotation; + switch (realTypeAnnotation.type) { case 'ReservedFunctionValueTypeAnnotation': - switch (typeAnnotation.name) { + switch (realTypeAnnotation.name) { case 'RootTag': return wrap('.getNumber()'); default: - (typeAnnotation.name: empty); + (realTypeAnnotation.name: empty); throw new Error( - `Unknown prop type for "${arg.name}", found: "${typeAnnotation.name}"`, + `Unknown prop type for "${arg.name}, found: ${realTypeAnnotation.name}"`, ); } case 'StringTypeAnnotation': @@ -91,27 +96,26 @@ function traverseArg(arg, index): string { case 'FunctionTypeAnnotation': return `std::move(${wrap('.getObject(rt).getFunction(rt)')})`; case 'GenericObjectTypeAnnotation': - case 'TypeAliasTypeAnnotation': // TODO: Handle aliases case 'ObjectTypeAnnotation': return wrap('.getObject(rt)'); case 'AnyTypeAnnotation': throw new Error(`Any type is not allowed in params for "${arg.name}"`); default: // TODO (T65847278): Figure out why this does not work. - // (typeAnnotation.type: empty); + // (type: empty); throw new Error( - `Unknown prop type for "${arg.name}", found: "${typeAnnotation.type}"`, + `Unknown prop type for "${arg.name}, found: ${realTypeAnnotation.type}"`, ); } } -function traverseProperty(property): string { +function traverseProperty(property, aliases): string { const propertyTemplate = property.typeAnnotation.returnTypeAnnotation.type === 'VoidTypeAnnotation' ? voidPropertyTemplate : nonvoidPropertyTemplate; const traversedArgs = property.typeAnnotation.params - .map(traverseArg) + .map((p, i) => traverseArg(p, i, aliases)) .join(', '); return propertyTemplate .replace(/::_PROPERTY_NAME_::/g, property.name) @@ -138,9 +142,9 @@ module.exports = { const modules = Object.keys(nativeModules) .map(name => { - const {properties} = nativeModules[name]; + const {aliases, properties} = nativeModules[name]; const traversedProperties = properties - .map(property => traverseProperty(property)) + .map(property => traverseProperty(property, aliases)) .join('\n'); return moduleTemplate .replace(/::_MODULE_PROPERTIES_::/g, traversedProperties) diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleH.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleH.js index 5de8f8ee3c6..fb41d160b5b 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleH.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleH.js @@ -14,8 +14,12 @@ import type { SchemaType, FunctionTypeAnnotationParamTypeAnnotation, FunctionTypeAnnotationReturn, + TypeAliasTypeAnnotation, + ObjectTypeAliasTypeShape, } from '../../CodegenSchema'; +const {getTypeAliasTypeAnnotation} = require('./ObjCppUtils/Utils'); + type FilesOutput = Map; const moduleTemplate = ` @@ -51,17 +55,23 @@ namespace react { function translatePrimitiveJSTypeToCpp( typeAnnotation: | FunctionTypeAnnotationParamTypeAnnotation - | FunctionTypeAnnotationReturn, + | FunctionTypeAnnotationReturn + | TypeAliasTypeAnnotation, createErrorMessage: (typeName: string) => string, + aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>, ) { - switch (typeAnnotation.type) { + const realTypeAnnotation = + typeAnnotation.type === 'TypeAliasTypeAnnotation' + ? getTypeAliasTypeAnnotation(typeAnnotation.name, aliases) + : typeAnnotation; + switch (realTypeAnnotation.type) { case 'ReservedFunctionValueTypeAnnotation': - switch (typeAnnotation.name) { + switch (realTypeAnnotation.name) { case 'RootTag': return 'double'; default: - (typeAnnotation.name: empty); - throw new Error(createErrorMessage(typeAnnotation.name)); + (realTypeAnnotation.name: empty); + throw new Error(createErrorMessage(realTypeAnnotation.name)); } case 'VoidTypeAnnotation': return 'void'; @@ -74,7 +84,6 @@ function translatePrimitiveJSTypeToCpp( return 'int'; case 'BooleanTypeAnnotation': return 'bool'; - // case 'TypeAliasTypeAnnotation': // TODO: Handle aliases case 'GenericObjectTypeAnnotation': case 'ObjectTypeAnnotation': return 'jsi::Object'; @@ -86,8 +95,8 @@ function translatePrimitiveJSTypeToCpp( return 'jsi::Value'; default: // TODO (T65847278): Figure out why this does not work. - // (typeAnnotation.type: empty); - throw new Error(createErrorMessage(typeAnnotation.type)); + // (type: empty); + throw new Error(createErrorMessage(realTypeAnnotation.type)); } } @@ -114,7 +123,7 @@ module.exports = { const modules = Object.keys(nativeModules) .map(name => { - const {properties} = nativeModules[name]; + const {aliases, properties} = nativeModules[name]; const traversedProperties = properties .map(prop => { const traversedArgs = prop.typeAnnotation.params @@ -123,6 +132,7 @@ module.exports = { param.typeAnnotation, typeName => `Unsupported type for param "${param.name}" in ${prop.name}. Found: ${typeName}`, + aliases, ); const isObject = translatedParam.startsWith('jsi::'); return ( @@ -140,6 +150,7 @@ module.exports = { prop.typeAnnotation.returnTypeAnnotation, typeName => `Unsupported return type for ${prop.name}. Found: ${typeName}`, + aliases, ), ) .replace( diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleHObjCpp.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleHObjCpp.js index a2fd47e7c34..41ebb294c0d 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleHObjCpp.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleHObjCpp.js @@ -15,13 +15,17 @@ import type { FunctionTypeAnnotationParam, FunctionTypeAnnotationReturn, ObjectParamTypeAnnotation, + ObjectTypeAliasTypeShape, } from '../../CodegenSchema'; const { translateObjectsForStructs, capitalizeFirstLetter, + getNamespacedStructName, } = require('./ObjCppUtils/GenerateStructs'); +const {getTypeAliasTypeAnnotation} = require('./ObjCppUtils/Utils'); + type FilesOutput = Map; const moduleTemplate = ` /** @@ -101,20 +105,26 @@ const constants = `- (facebook::react::ModuleConstants string, + aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>, ) { const {nullable, typeAnnotation} = param; function wrapIntoNullableIfNeeded(generatedType: string) { return nullable ? `${generatedType} _Nullable` : generatedType; } - switch (typeAnnotation.type) { + + const realTypeAnnotation = + typeAnnotation.type === 'TypeAliasTypeAnnotation' + ? getTypeAliasTypeAnnotation(typeAnnotation.name, aliases) + : typeAnnotation; + switch (realTypeAnnotation.type) { case 'ReservedFunctionValueTypeAnnotation': - switch (typeAnnotation.name) { + switch (realTypeAnnotation.name) { case 'RootTag': return nullable ? 'NSNumber *' : 'double'; default: - (typeAnnotation.name: empty); - throw new Error(createErrorMessage(typeAnnotation.name)); + (realTypeAnnotation.name: empty); + throw new Error(createErrorMessage(realTypeAnnotation.name)); } case 'StringTypeAnnotation': return wrapIntoNullableIfNeeded('NSString *'); @@ -124,19 +134,21 @@ function translatePrimitiveJSTypeToObjCType( return nullable ? 'NSNumber *' : 'double'; case 'BooleanTypeAnnotation': return nullable ? 'NSNumber * _Nullable' : 'BOOL'; - case 'TypeAliasTypeAnnotation': // TODO: Handle aliases + case 'ObjectTypeAnnotation': + if (typeAnnotation.type === 'TypeAliasTypeAnnotation') { + return getNamespacedStructName(typeAnnotation.name) + ' &'; + } + return wrapIntoNullableIfNeeded('NSDictionary *'); case 'GenericObjectTypeAnnotation': return wrapIntoNullableIfNeeded('NSDictionary *'); case 'ArrayTypeAnnotation': return wrapIntoNullableIfNeeded('NSArray *'); case 'FunctionTypeAnnotation': return 'RCTResponseSenderBlock'; - case 'ObjectTypeAnnotation': - return wrapIntoNullableIfNeeded('NSDictionary *'); default: // TODO (T65847278): Figure out why this does not work. - // (typeAnnotation.type: empty); - throw new Error(createErrorMessage(typeAnnotation.type)); + // (type: empty); + throw new Error(createErrorMessage(realTypeAnnotation.type)); } } @@ -184,23 +196,26 @@ function translatePrimitiveJSTypeToObjCTypeForReturn( function handleArrayOfObjects( objectForGeneratingStructs: Array, - param: FunctionTypeAnnotationParam, + propOrParam: FunctionTypeAnnotationParam, name: string, ) { if ( - param.typeAnnotation.type === 'ArrayTypeAnnotation' && - param.typeAnnotation.elementType && - param.typeAnnotation.elementType.type === 'ObjectTypeAnnotation' && - param.typeAnnotation.elementType.properties + propOrParam.typeAnnotation.type === 'ArrayTypeAnnotation' && + propOrParam.typeAnnotation.elementType ) { - const {elementType} = param.typeAnnotation; - const {properties} = elementType; - if (properties && properties.length > 0) { + const typeAnnotation = propOrParam.typeAnnotation.elementType; + const type = typeAnnotation.type; + + if ( + type === 'ObjectTypeAnnotation' && + typeAnnotation.properties && + typeAnnotation.properties.length > 0 + ) { objectForGeneratingStructs.push({ name, object: { type: 'ObjectTypeAnnotation', - properties, + properties: typeAnnotation.properties, }, }); } @@ -237,7 +252,7 @@ module.exports = { .sort() .map(name => { const objectForGeneratingStructs: Array = []; - const {properties} = nativeModules[name]; + const {aliases, properties} = nativeModules[name]; const implementations = properties .map(prop => { const nativeArgs = prop.typeAnnotation.params @@ -250,36 +265,55 @@ module.exports = { const variableName = capitalizeFirstLetter(prop.name) + capitalizeFirstLetter(param.name); + const structName = 'Spec' + variableName; objectForGeneratingStructs.push({ - name: variableName, + name: structName, object: { type: 'ObjectTypeAnnotation', properties: param.typeAnnotation.properties, }, }); - paramObjCType = `JS::Native::_MODULE_NAME_::::Spec${variableName}&`; + paramObjCType = getNamespacedStructName(structName) + ' &'; - param.typeAnnotation.properties.map(aProp => - handleArrayOfObjects( + param.typeAnnotation.properties.map(aProp => { + return handleArrayOfObjects( objectForGeneratingStructs, aProp, - capitalizeFirstLetter(prop.name) + + 'Spec' + + capitalizeFirstLetter(prop.name) + capitalizeFirstLetter(param.name) + capitalizeFirstLetter(aProp.name) + 'Element', - ), + ); + }); + } else if ( + param.typeAnnotation.type === 'TypeAliasTypeAnnotation' + ) { + const typeAnnotation = getTypeAliasTypeAnnotation( + param.typeAnnotation.name, + aliases, ); + if (typeAnnotation.type === 'ObjectTypeAnnotation') { + paramObjCType = + getNamespacedStructName(param.typeAnnotation.name) + ' &'; + } else { + throw Error( + `Unsupported type for "${param.typeAnnotation.name}". Found: ${typeAnnotation.type}`, + ); + } } else { paramObjCType = translatePrimitiveJSTypeToObjCType( param, typeName => `Unsupported type for param "${param.name}" in ${prop.name}. Found: ${typeName}`, + aliases, ); handleArrayOfObjects( objectForGeneratingStructs, param, - capitalizeFirstLetter(prop.name) + + 'Spec' + + capitalizeFirstLetter(prop.name) + capitalizeFirstLetter(param.name) + 'Element', ); @@ -296,8 +330,7 @@ module.exports = { returnTypeAnnotation.properties ) { objectForGeneratingStructs.push({ - name: capitalizeFirstLetter(prop.name) + 'ReturnType', - + name: 'Spec' + capitalizeFirstLetter(prop.name) + 'ReturnType', object: { type: 'ObjectTypeAnnotation', properties: returnTypeAnnotation.properties, @@ -327,10 +360,44 @@ module.exports = { return implementation; }) .join('\n'); + + Object.keys(aliases) + .reverse() + .map((aliasName, i) => { + const alias = aliases[aliasName]; + + let paramObjCType = ''; + + switch (alias.type) { + case 'ObjectTypeAnnotation': + if (alias.properties) { + objectForGeneratingStructs.push({ + name: aliasName, + object: { + type: 'ObjectTypeAnnotation', + properties: alias.properties, + }, + }); + paramObjCType = getNamespacedStructName(alias.name) + ' &'; + } + break; + default: + throw Error( + `Unsupported type for "${aliasName}". Found: ${alias.type}`, + ); + } + return `${i === 0 ? '' : aliasName}:(${paramObjCType})${aliasName}`; + }) + .join('\n'); + return protocolTemplate .replace( /::_STRUCTS_::/g, - translateObjectsForStructs(objectForGeneratingStructs, name), + translateObjectsForStructs( + objectForGeneratingStructs, + name, + aliases, + ), ) .replace(/::_MODULE_PROPERTIES_::/g, implementations) .replace(/::_MODULE_NAME_::/g, name) diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleMm.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleMm.js index 448541cd995..251c242a7c3 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleMm.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleMm.js @@ -13,7 +13,10 @@ import type {SchemaType, NativeModuleShape} from '../../CodegenSchema'; const {capitalizeFirstLetter} = require('./ObjCppUtils/GenerateStructs'); -const {flatObjects} = require('./ObjCppUtils/Utils'); +const { + flatObjects, + getTypeAliasTypeAnnotation, +} = require('./ObjCppUtils/Utils'); type FilesOutput = Map; @@ -40,16 +43,16 @@ const moduleTemplate = ` }`.trim(); const getterTemplate = ` -@implementation RCTCxxConvert (Native::_MODULE_NAME_::_Spec::_GETTER_NAME_::) -+ (RCTManagedPointer *)JS_Native::_MODULE_NAME_::_Spec::_GETTER_NAME_:::(id)json +@implementation RCTCxxConvert (Native::_MODULE_NAME_::_::_GETTER_NAME_::) ++ (RCTManagedPointer *)JS_Native::_MODULE_NAME_::_::_GETTER_NAME_:::(id)json { - return facebook::react::managedPointer(json); + return facebook::react::managedPointer(json); } @end `; const argConvertionTemplate = - '\n setMethodArgConversionSelector(@"::_ARG_NAME_::", ::_ARG_NUMBER_::, @"JS_Native::_MODULE_NAME_::_Spec::_SELECTOR_NAME_:::");'; + '\n setMethodArgConversionSelector(@"::_ARG_NAME_::", ::_ARG_NUMBER_::, @"JS_Native::_MODULE_NAME_::_::_SELECTOR_NAME_:::");'; const template = ` /** @@ -171,46 +174,65 @@ module.exports = { const module: NativeModuleShape = nativeModules[moduleName]; return acc.concat( flatObjects( - module.properties.reduce((moduleAcc, property) => { - const {returnTypeAnnotation} = property.typeAnnotation; - if (returnTypeAnnotation.type === 'ObjectTypeAnnotation') { - const {properties} = returnTypeAnnotation; - if (properties) { - moduleAcc.push({ - name: capitalizeFirstLetter(property.name) + 'ReturnType', - object: { - type: 'ObjectTypeAnnotation', - properties: properties, - }, - }); + module.properties + .reduce((moduleAcc, property) => { + const {returnTypeAnnotation} = property.typeAnnotation; + if (returnTypeAnnotation.type === 'ObjectTypeAnnotation') { + const {properties} = returnTypeAnnotation; + if (properties) { + moduleAcc.push({ + name: + 'Spec' + + capitalizeFirstLetter(property.name) + + 'ReturnType', + object: { + type: 'ObjectTypeAnnotation', + properties: properties, + }, + }); + } } - } - if (property.typeAnnotation.params) { - return moduleAcc.concat( - property.typeAnnotation.params - .map(param => { - if ( - param.typeAnnotation.type === 'ObjectTypeAnnotation' - ) { - const {properties} = param.typeAnnotation; - if (properties) { - return { - name: - capitalizeFirstLetter(property.name) + - capitalizeFirstLetter(param.name), - object: { - type: 'ObjectTypeAnnotation', - properties: properties, - }, - }; + if (property.typeAnnotation.params) { + return moduleAcc.concat( + property.typeAnnotation.params + .map(param => { + if ( + param.typeAnnotation.type === 'ObjectTypeAnnotation' + ) { + const {properties} = param.typeAnnotation; + if (properties) { + return { + name: + 'Spec' + + capitalizeFirstLetter(property.name) + + capitalizeFirstLetter(param.name), + object: { + type: 'ObjectTypeAnnotation', + properties: properties, + }, + }; + } } - } - }) - .filter(Boolean), - ); - } - return moduleAcc; - }, []), + }) + .filter(Boolean), + ); + } + return moduleAcc; + }, []) + .concat( + Object.keys(module.aliases).map(aliasName => { + const alias = getTypeAliasTypeAnnotation( + aliasName, + module.aliases, + ); + return { + name: aliasName, + object: {type: alias.type, properties: alias.properties}, + }; + }), + ), + false, + module.aliases, ) .map(object => getterTemplate @@ -224,7 +246,7 @@ module.exports = { const modules = Object.keys(nativeModules) .map(name => { - const {properties} = nativeModules[name]; + const {aliases, properties} = nativeModules[name]; const translatedMethods = properties .map(property => translateMethodForImplementation(property)) .join('\n'); @@ -254,19 +276,33 @@ module.exports = { properties .map(({name: propertyName, typeAnnotation: {params}}) => params - .map((param, index) => - param.typeAnnotation.type === 'ObjectTypeAnnotation' && - param.typeAnnotation.properties - ? argConvertionTemplate - .replace( - '::_SELECTOR_NAME_::', - capitalizeFirstLetter(propertyName) + - capitalizeFirstLetter(param.name), + .map((param, index) => { + const typeAnnotation = + param.typeAnnotation.type === 'TypeAliasTypeAnnotation' + ? getTypeAliasTypeAnnotation( + param.typeAnnotation.name, + aliases, ) - .replace('::_ARG_NUMBER_::', index.toString()) - .replace('::_ARG_NAME_::', propertyName) - : '', - ) + : param.typeAnnotation; + const selectorName = + param.typeAnnotation.type === 'TypeAliasTypeAnnotation' + ? param.typeAnnotation.name + : 'Spec' + + capitalizeFirstLetter(propertyName) + + capitalizeFirstLetter(param.name); + + if ( + typeAnnotation.type === 'ObjectTypeAnnotation' && + typeAnnotation.properties + ) { + return argConvertionTemplate + .replace('::_SELECTOR_NAME_::', selectorName) + .replace('::_ARG_NUMBER_::', index.toString()) + .replace('::_ARG_NAME_::', propertyName); + } + + return ''; + }) .join(''), ) .join(''), diff --git a/packages/react-native-codegen/src/generators/modules/ObjCppUtils/GenerateStructs.js b/packages/react-native-codegen/src/generators/modules/ObjCppUtils/GenerateStructs.js index 9be5bcbd537..e860a663270 100644 --- a/packages/react-native-codegen/src/generators/modules/ObjCppUtils/GenerateStructs.js +++ b/packages/react-native-codegen/src/generators/modules/ObjCppUtils/GenerateStructs.js @@ -10,11 +10,15 @@ 'use strict'; -import type {ObjectParamTypeAnnotation} from '../../../CodegenSchema'; +import type { + ObjectParamTypeAnnotation, + ObjectTypeAliasTypeShape, +} from '../../../CodegenSchema'; const { flatObjects, capitalizeFirstLetter, getSafePropertyName, + getTypeAliasTypeAnnotation, } = require('./Utils'); const {generateStructsForConstants} = require('./GenerateStructsForConstants'); @@ -25,42 +29,38 @@ const template = ` const structTemplate = ` namespace JS { namespace Native::_MODULE_NAME_:: { - struct Spec::_STRUCT_NAME_:: { + struct ::_STRUCT_NAME_:: { ::_STRUCT_PROPERTIES_:: - Spec::_STRUCT_NAME_::(NSDictionary *const v) : _v(v) {} + ::_STRUCT_NAME_::(NSDictionary *const v) : _v(v) {} private: NSDictionary *_v; }; } } -@interface RCTCxxConvert (Native::_MODULE_NAME_::_Spec::_STRUCT_NAME_::) -+ (RCTManagedPointer *)JS_Native::_MODULE_NAME_::_Spec::_STRUCT_NAME_:::(id)json; +@interface RCTCxxConvert (Native::_MODULE_NAME_::_::_STRUCT_NAME_::) ++ (RCTManagedPointer *)JS_Native::_MODULE_NAME_::_::_STRUCT_NAME_:::(id)json; @end `; const inlineTemplate = ` -inline ::_RETURN_TYPE_::JS::Native::_MODULE_NAME_::::Spec::_STRUCT_NAME_::::::_PROPERTY_NAME_::() const +inline ::_RETURN_TYPE_::JS::Native::_MODULE_NAME_::::::_STRUCT_NAME_::::::_PROPERTY_NAME_::() const { id const p = _v[@"::_PROPERTY_NAME_::"]; return ::_RETURN_VALUE_::; } `; -function getNamespacedStructName( - structName: string, - property: ObjectParamTypeAnnotation, -) { - return `JS::Native::_MODULE_NAME_::::Spec${structName}${capitalizeFirstLetter( - getSafePropertyName(property), - )}`; +function getNamespacedStructName(structName: string): string { + return `JS::Native::_MODULE_NAME_::::${structName}`; } function getElementTypeForArray( property: ObjectParamTypeAnnotation, name: string, moduleName: string, + aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>, ): string { const {typeAnnotation} = property; @@ -81,7 +81,11 @@ function getElementTypeForArray( return 'id'; } - const {type} = typeAnnotation.elementType; + const type = + typeAnnotation.elementType.type === 'TypeAliasTypeAnnotation' + ? getTypeAliasTypeAnnotation(typeAnnotation.elementType.name, aliases) + .type + : typeAnnotation.elementType.type; switch (type) { case 'StringTypeAnnotation': return 'NSString *'; @@ -91,8 +95,11 @@ function getElementTypeForArray( case 'Int32TypeAnnotation': return 'double'; case 'ObjectTypeAnnotation': - return getNamespacedStructName(name, property) + 'Element'; - case 'TypeAliasTypeAnnotation': // TODO: Handle aliases + const structName = + typeAnnotation.elementType.type === 'TypeAliasTypeAnnotation' + ? typeAnnotation.elementType.name + : `${property.name}Element`; + return getNamespacedStructName(structName); case 'GenericObjectTypeAnnotation': // TODO(T67565166): Generic objects are not type safe and should be disallowed in the schema. This case should throw an error once it is disallowed in schema. console.error( @@ -118,6 +125,7 @@ function getInlineMethodSignature( property: ObjectParamTypeAnnotation, name: string, moduleName: string, + aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>, ): string { const {typeAnnotation} = property; function markOptionalTypeIfNecessary(type: string) { @@ -135,14 +143,28 @@ function getInlineMethodSignature( return `id ${getSafePropertyName(property)}() const;`; } - switch (typeAnnotation.type) { + const realTypeAnnotation = + typeAnnotation.type === 'TypeAliasTypeAnnotation' + ? getTypeAliasTypeAnnotation(typeAnnotation.name, aliases) + : typeAnnotation; + + const variableName = + typeAnnotation.type === 'TypeAliasTypeAnnotation' + ? `${capitalizeFirstLetter(typeAnnotation.name)}` + : `${capitalizeFirstLetter(name)}${capitalizeFirstLetter( + getSafePropertyName(property), + )}`; + + switch (realTypeAnnotation.type) { case 'ReservedFunctionValueTypeAnnotation': - switch (typeAnnotation.name) { + switch (realTypeAnnotation.name) { case 'RootTag': return `double ${getSafePropertyName(property)}() const;`; default: - (typeAnnotation.name: empty); - throw new Error(`Unknown prop type, found: ${typeAnnotation.name}"`); + (realTypeAnnotation.name: empty); + throw new Error( + `Unknown prop type, found: ${realTypeAnnotation.name}"`, + ); } case 'StringTypeAnnotation': return `NSString *${getSafePropertyName(property)}() const;`; @@ -157,10 +179,9 @@ function getInlineMethodSignature( property, )}() const;`; case 'ObjectTypeAnnotation': - return ( - markOptionalTypeIfNecessary(getNamespacedStructName(name, property)) + - ` ${getSafePropertyName(property)}() const;` - ); + return `${markOptionalTypeIfNecessary( + getNamespacedStructName(variableName), + )} ${getSafePropertyName(property)}() const;`; case 'GenericObjectTypeAnnotation': case 'AnyTypeAnnotation': return `id ${ @@ -172,11 +193,12 @@ function getInlineMethodSignature( property, name, moduleName, + aliases, )}>`, )} ${getSafePropertyName(property)}() const;`; case 'FunctionTypeAnnotation': default: - throw new Error(`Unknown prop type, found: ${typeAnnotation.type}"`); + throw new Error(`Unknown prop type, found: ${realTypeAnnotation.type}"`); } } @@ -184,6 +206,7 @@ function getInlineMethodImplementation( property: ObjectParamTypeAnnotation, name: string, moduleName: string, + aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>, ): string { const {typeAnnotation} = property; function markOptionalTypeIfNecessary(type: string): string { @@ -216,7 +239,12 @@ function getInlineMethodImplementation( throw new Error(`Cannot get array element type for ${name}`); } - const {type} = typeAnnotation.elementType; + const type = + typeAnnotation.elementType.type === 'TypeAliasTypeAnnotation' + ? getTypeAliasTypeAnnotation(typeAnnotation.elementType.name, aliases) + .type + : typeAnnotation.elementType.type; + switch (type) { case 'StringTypeAnnotation': return `RCTBridgingToString(${element})`; @@ -228,8 +256,11 @@ function getInlineMethodImplementation( case 'BooleanTypeAnnotation': return `RCTBridgingToBool(${element})`; case 'ObjectTypeAnnotation': - return `${getNamespacedStructName(name, property)}Element(${element})`; - case 'TypeAliasTypeAnnotation': // TODO: Handle aliases + const structName = + typeAnnotation.elementType.type === 'TypeAliasTypeAnnotation' + ? `${typeAnnotation.elementType.name}(${element})` + : `${getSafePropertyName(property)}Element(${element})`; + return getNamespacedStructName(structName); case 'GenericObjectTypeAnnotation': return element; case 'AnyObjectTypeAnnotation': @@ -260,16 +291,23 @@ function getInlineMethodImplementation( .replace(/::_RETURN_VALUE_::/, 'p'); } - switch (typeAnnotation.type) { + const realTypeAnnotation = + typeAnnotation.type === 'TypeAliasTypeAnnotation' + ? getTypeAliasTypeAnnotation(typeAnnotation.name, aliases) + : typeAnnotation; + + switch (realTypeAnnotation.type) { case 'ReservedFunctionValueTypeAnnotation': - switch (typeAnnotation.name) { + switch (realTypeAnnotation.name) { case 'RootTag': return inlineTemplate .replace(/::_RETURN_TYPE_::/, 'double ') .replace(/::_RETURN_VALUE_::/, 'RCTBridgingToDouble(p)'); default: - (typeAnnotation.name: empty); - throw new Error(`Unknown prop type, found: ${typeAnnotation.name}"`); + (realTypeAnnotation.name: empty); + throw new Error( + `Unknown prop type, found: ${realTypeAnnotation.name}"`, + ); } case 'StringTypeAnnotation': return inlineTemplate @@ -300,19 +338,21 @@ function getInlineMethodImplementation( ) .replace(/::_RETURN_VALUE_::/, 'p'); case 'ObjectTypeAnnotation': + const structName = + typeAnnotation.type === 'TypeAliasTypeAnnotation' + ? `${capitalizeFirstLetter(typeAnnotation.name)}` + : `${name}${capitalizeFirstLetter(getSafePropertyName(property))}`; + const namespacedStructName = getNamespacedStructName(structName); return inlineTemplate .replace( /::_RETURN_TYPE_::/, - markOptionalTypeIfNecessary(getNamespacedStructName(name, property)), + markOptionalTypeIfNecessary(namespacedStructName), ) .replace( /::_RETURN_VALUE_::/, property.optional - ? `(p == nil ? folly::none : folly::make_optional(${getNamespacedStructName( - name, - property, - )}(p)))` - : `${getNamespacedStructName(name, property)}(p)`, + ? `(p == nil ? folly::none : folly::make_optional(${namespacedStructName}(p)))` + : `${namespacedStructName}(p)`, ); case 'ArrayTypeAnnotation': return inlineTemplate @@ -323,6 +363,7 @@ function getInlineMethodImplementation( property, name, moduleName, + aliases, )}>`, ), ) @@ -332,13 +373,14 @@ function getInlineMethodImplementation( property, name, moduleName, + aliases, )}(id itemValue_0) { return ${bridgeArrayElementValueIfNecessary( 'itemValue_0', )}; })`, ); case 'FunctionTypeAnnotation': default: - throw new Error(`Unknown prop type, found: ${typeAnnotation.type}"`); + throw new Error(`Unknown prop type, found: ${realTypeAnnotation.type}"`); } } @@ -353,15 +395,21 @@ function translateObjectsForStructs( |}>, >, moduleName: string, + aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>, ): string { - const flattenObjects = flatObjects(annotations); + const flattenObjects = flatObjects(annotations, false, aliases); const translatedInlineMethods = flattenObjects .reduce( (acc, object) => acc.concat( object.properties.map(property => - getInlineMethodImplementation(property, object.name, moduleName) + getInlineMethodImplementation( + property, + object.name, + moduleName, + aliases, + ) .replace(/::_PROPERTY_NAME_::/g, getSafePropertyName(property)) .replace(/::_STRUCT_NAME_::/g, object.name), ), @@ -371,22 +419,26 @@ function translateObjectsForStructs( .join('\n'); const translatedStructs = flattenObjects - .map(object => - structTemplate + .map(object => { + return structTemplate .replace( /::_STRUCT_PROPERTIES_::/g, object.properties .map(property => - getInlineMethodSignature(property, object.name, moduleName), + getInlineMethodSignature( + property, + object.name, + moduleName, + aliases, + ), ) .join('\n '), ) - .replace(/::_STRUCT_NAME_::/g, object.name), - ) + .replace(/::_STRUCT_NAME_::/g, object.name); + }) .reverse() .join('\n'); - - const translatedConstants = generateStructsForConstants(annotations); + const translatedConstants = generateStructsForConstants(annotations, aliases); return template .replace(/::_STRUCTS_::/, translatedStructs) @@ -396,4 +448,5 @@ function translateObjectsForStructs( module.exports = { translateObjectsForStructs, capitalizeFirstLetter, + getNamespacedStructName, }; diff --git a/packages/react-native-codegen/src/generators/modules/ObjCppUtils/GenerateStructsForConstants.js b/packages/react-native-codegen/src/generators/modules/ObjCppUtils/GenerateStructsForConstants.js index 5d8dc29af72..614f2fe4a42 100644 --- a/packages/react-native-codegen/src/generators/modules/ObjCppUtils/GenerateStructsForConstants.js +++ b/packages/react-native-codegen/src/generators/modules/ObjCppUtils/GenerateStructsForConstants.js @@ -10,8 +10,15 @@ 'use strict'; -import type {ObjectParamTypeAnnotation} from '../../../CodegenSchema'; -const {flatObjects, capitalizeFirstLetter} = require('./Utils'); +import type { + ObjectParamTypeAnnotation, + ObjectTypeAliasTypeShape, +} from '../../../CodegenSchema'; +const { + flatObjects, + capitalizeFirstLetter, + getTypeAliasTypeAnnotation, +} = require('./Utils'); const structTemplate = ` namespace JS { @@ -54,6 +61,7 @@ inline JS::Native::_MODULE_NAME_::::::_STRUCT_NAME_::::Builder::Builder(::_STRUC function getBuilderInputFieldDeclaration( property: ObjectParamTypeAnnotation, name: string, + aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>, ): string { function markRequiredIfNecessary(annotation) { if (!property.optional) { @@ -70,14 +78,26 @@ function getBuilderInputFieldDeclaration( ); } - switch (typeAnnotation.type) { + const realTypeAnnotation = + typeAnnotation.type === 'TypeAliasTypeAnnotation' + ? getTypeAliasTypeAnnotation(typeAnnotation.name, aliases) + : typeAnnotation; + + const variableName = + typeAnnotation.type === 'TypeAliasTypeAnnotation' + ? typeAnnotation.name + : `${name}${capitalizeFirstLetter(property.name)}`; + + switch (realTypeAnnotation.type) { case 'ReservedFunctionValueTypeAnnotation': - switch (typeAnnotation.name) { + switch (realTypeAnnotation.name) { case 'RootTag': return markRequiredIfNecessary('double'); default: - (typeAnnotation.name: empty); - throw new Error(`Unknown prop type, found: ${typeAnnotation.name}"`); + (realTypeAnnotation.name: empty); + throw new Error( + `Unknown prop type, found: ${realTypeAnnotation.name}"`, + ); } case 'StringTypeAnnotation': if (property.optional) { @@ -92,11 +112,8 @@ function getBuilderInputFieldDeclaration( return markRequiredIfNecessary('bool'); case 'ObjectTypeAnnotation': return markRequiredIfNecessary( - `JS::Native::_MODULE_NAME_::::Spec${name}${capitalizeFirstLetter( - property.name, - )}::Builder`, + `JS::Native::_MODULE_NAME_::::${variableName}::Builder`, ); - case 'TypeAliasTypeAnnotation': // TODO: Handle aliases case 'GenericObjectTypeAnnotation': case 'AnyTypeAnnotation': if (property.optional) { @@ -107,7 +124,7 @@ function getBuilderInputFieldDeclaration( return markRequiredIfNecessary('std::vector>'); case 'FunctionTypeAnnotation': default: - throw new Error(`Unknown prop type, found: ${typeAnnotation.type}"`); + throw new Error(`Unknown prop type, found: ${realTypeAnnotation.type}"`); } } @@ -160,7 +177,10 @@ function unsafeGetter(name: string, optional: boolean) { `.trim(); } -function getObjectProperty(property: ObjectParamTypeAnnotation): string { +function getObjectProperty( + property: ObjectParamTypeAnnotation, + aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>, +): string { const {typeAnnotation} = property; // TODO(T67898313): Workaround for NativeLinking's use of union type. This check may be removed once typeAnnotation is non-optional. @@ -170,13 +190,22 @@ function getObjectProperty(property: ObjectParamTypeAnnotation): string { ); } - switch (typeAnnotation.type) { + const type = + typeAnnotation.type === 'TypeAliasTypeAnnotation' + ? getTypeAliasTypeAnnotation(typeAnnotation.name, aliases).type + : typeAnnotation.type; + + switch (type) { case 'ReservedFunctionValueTypeAnnotation': + if (typeAnnotation.name == null) { + throw new Error(`Prop type ${type} has no name.`); + } switch (typeAnnotation.name) { case 'RootTag': return numberGetter(property.name, property.optional); default: - (typeAnnotation.name: empty); + // TODO (T65847278): Figure out why this does not work. + // (typeAnnotation.name: empty); throw new Error(`Unknown prop type, found: ${typeAnnotation.name}"`); } case 'NumberTypeAnnotation': @@ -186,7 +215,6 @@ function getObjectProperty(property: ObjectParamTypeAnnotation): string { case 'BooleanTypeAnnotation': return boolGetter(property.name, property.optional); case 'StringTypeAnnotation': - case 'TypeAliasTypeAnnotation': // TODO: Handle aliases case 'GenericObjectTypeAnnotation': case 'AnyTypeAnnotation': return safeGetter(property.name, property.optional); @@ -196,7 +224,7 @@ function getObjectProperty(property: ObjectParamTypeAnnotation): string { return arrayGetter(property.name, property.optional); case 'FunctionTypeAnnotation': default: - throw new Error(`Unknown prop type, found: ${typeAnnotation.type}"`); + throw new Error(`Unknown prop type, found: ${type}"`); } } @@ -210,8 +238,9 @@ function generateStructsForConstants( |}>, |}>, >, + aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>, ): string { - return flatObjects(annotations, true) + return flatObjects(annotations, true, aliases) .reduce( (acc, object) => acc.concat( @@ -220,14 +249,18 @@ function generateStructsForConstants( /::_INPUT_::/g, object.properties .map(property => - getBuilderInputFieldDeclaration(property, object.name), + getBuilderInputFieldDeclaration( + property, + object.name, + aliases, + ), ) .join('\n '), ) .replace( /::_PROPERTIES_::/g, object.properties - .map(property => getObjectProperty(property)) + .map(property => getObjectProperty(property, aliases)) .join('\n'), ) .replace(/::_STRUCT_NAME_::/g, object.name), diff --git a/packages/react-native-codegen/src/generators/modules/ObjCppUtils/Utils.js b/packages/react-native-codegen/src/generators/modules/ObjCppUtils/Utils.js index eb7d73974e8..8c921c075c6 100644 --- a/packages/react-native-codegen/src/generators/modules/ObjCppUtils/Utils.js +++ b/packages/react-native-codegen/src/generators/modules/ObjCppUtils/Utils.js @@ -10,7 +10,10 @@ 'use strict'; -import type {ObjectParamTypeAnnotation} from '../../../CodegenSchema'; +import type { + ObjectParamTypeAnnotation, + ObjectTypeAliasTypeShape, +} from '../../../CodegenSchema'; function capitalizeFirstLetter(string: string): string { return string.charAt(0).toUpperCase() + string.slice(1); @@ -27,6 +30,7 @@ function flatObjects( |}>, >, forConstants: boolean = false, + aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>, ): $ReadOnlyArray< $ReadOnly<{| name: string, @@ -37,17 +41,23 @@ function flatObjects( properties: $ReadOnlyArray, name: string, |}> = annotations - .map(annotation => ({ - name: annotation.name, - properties: annotation.object.properties, - })) + .map(annotation => { + if (annotation.object.type === 'TypeAliasTypeAnnotation') { + const alias = getTypeAliasTypeAnnotation(annotation.name, aliases); + return {name: annotation.name, properties: alias.properties}; + } + return { + name: annotation.name, + properties: annotation.object.properties, + }; + }) .filter( annotation => - (annotation.name === 'GetConstantsReturnType') === forConstants, + (annotation.name === 'SpecGetConstantsReturnType') === forConstants, ) .filter( annotation => - annotation.name !== 'GetConstantsReturnType' || + annotation.name !== 'SpecGetConstantsReturnType' || annotation.properties.length > 0, ); @@ -94,8 +104,35 @@ function getSafePropertyName(property: ObjectParamTypeAnnotation): string { return property.name; } +function getTypeAliasTypeAnnotation( + name: string, + aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>, +): $ReadOnly { + const typeAnnotation = aliases[name]; + if (!typeAnnotation) { + throw Error(`No type annotation found for "${name}" in schema`); + } + if (typeAnnotation.type === 'ObjectTypeAnnotation') { + if (typeAnnotation.properties) { + return typeAnnotation; + } + + throw new Error( + `Unsupported type for "${name}". Please provide properties.`, + ); + } + if (typeAnnotation.type === 'TypeAliasTypeAnnotation') { + return getTypeAliasTypeAnnotation(typeAnnotation.name, aliases); + } + + throw Error( + `Unsupported type annotation in alias "${name}", found: ${typeAnnotation.type}`, + ); +} + module.exports = { flatObjects, capitalizeFirstLetter, getSafePropertyName, + getTypeAliasTypeAnnotation, }; diff --git a/packages/react-native-codegen/src/generators/modules/__test_fixtures__/fixtures.js b/packages/react-native-codegen/src/generators/modules/__test_fixtures__/fixtures.js index 6feda946974..cea663c8b1b 100644 --- a/packages/react-native-codegen/src/generators/modules/__test_fixtures__/fixtures.js +++ b/packages/react-native-codegen/src/generators/modules/__test_fixtures__/fixtures.js @@ -707,10 +707,806 @@ const COMPLEX_OBJECTS: SchemaType = { }, }, }; + +const NATIVE_MODULES_WITH_TYPE_ALIASES: SchemaType = { + modules: { + AliasTurboModule: { + nativeModules: { + AliasTurboModule: { + aliases: { + Options: { + properties: [ + { + optional: false, + name: 'offset', + typeAnnotation: { + type: 'ObjectTypeAnnotation', + properties: [ + { + optional: false, + name: 'x', + typeAnnotation: { + type: 'NumberTypeAnnotation', + }, + }, + { + optional: false, + name: 'y', + typeAnnotation: { + type: 'NumberTypeAnnotation', + }, + }, + ], + }, + }, + { + optional: false, + name: 'size', + typeAnnotation: { + type: 'ObjectTypeAnnotation', + properties: [ + { + optional: false, + name: 'width', + typeAnnotation: { + type: 'NumberTypeAnnotation', + }, + }, + { + optional: false, + name: 'height', + typeAnnotation: { + type: 'NumberTypeAnnotation', + }, + }, + ], + }, + }, + { + optional: true, + name: 'displaySize', + typeAnnotation: { + type: 'ObjectTypeAnnotation', + properties: [ + { + optional: false, + name: 'width', + typeAnnotation: { + type: 'NumberTypeAnnotation', + }, + }, + { + optional: false, + name: 'height', + typeAnnotation: { + type: 'NumberTypeAnnotation', + }, + }, + ], + }, + }, + { + optional: true, + name: 'resizeMode', + typeAnnotation: { + type: 'StringTypeAnnotation', + }, + }, + { + optional: true, + name: 'allowExternalStorage', + typeAnnotation: { + type: 'BooleanTypeAnnotation', + }, + }, + ], + type: 'ObjectTypeAnnotation', + }, + }, + properties: [ + { + name: 'getConstants', + typeAnnotation: { + type: 'FunctionTypeAnnotation', + returnTypeAnnotation: { + nullable: false, + type: 'ObjectTypeAnnotation', + properties: [], + }, + params: [], + optional: false, + }, + }, + { + name: 'cropImage', + typeAnnotation: { + type: 'FunctionTypeAnnotation', + returnTypeAnnotation: { + nullable: false, + type: 'VoidTypeAnnotation', + }, + params: [ + { + nullable: false, + name: 'cropData', + typeAnnotation: { + type: 'TypeAliasTypeAnnotation', + name: 'Options', + }, + }, + ], + optional: false, + }, + }, + ], + }, + }, + }, + }, +}; + +const REAL_MODULE_EXAMPLE: SchemaType = { + modules: { + NativeCameraRollManager: { + nativeModules: { + CameraRollManager: { + aliases: { + PhotoIdentifierImage: { + type: 'ObjectTypeAnnotation', + properties: [ + { + optional: false, + name: 'uri', + typeAnnotation: { + type: 'StringTypeAnnotation', + }, + }, + { + optional: false, + name: 'playableDuration', + typeAnnotation: { + type: 'NumberTypeAnnotation', + }, + }, + { + optional: false, + name: 'width', + typeAnnotation: { + type: 'NumberTypeAnnotation', + }, + }, + { + optional: false, + name: 'height', + typeAnnotation: { + type: 'NumberTypeAnnotation', + }, + }, + { + optional: true, + name: 'isStored', + typeAnnotation: { + type: 'BooleanTypeAnnotation', + }, + }, + { + optional: false, + name: 'filename', + typeAnnotation: { + type: 'StringTypeAnnotation', + }, + }, + ], + }, + PhotoIdentifier: { + type: 'ObjectTypeAnnotation', + properties: [ + { + optional: false, + name: 'node', + typeAnnotation: { + type: 'ObjectTypeAnnotation', + properties: [ + { + optional: false, + name: 'image', + typeAnnotation: { + type: 'TypeAliasTypeAnnotation', + name: 'PhotoIdentifierImage', + }, + }, + { + optional: false, + name: 'type', + typeAnnotation: { + type: 'StringTypeAnnotation', + }, + }, + { + optional: false, + name: 'group_name', + typeAnnotation: { + type: 'StringTypeAnnotation', + }, + }, + { + optional: false, + name: 'timestamp', + typeAnnotation: { + type: 'NumberTypeAnnotation', + }, + }, + { + optional: false, + name: 'location', + typeAnnotation: { + type: 'ObjectTypeAnnotation', + properties: [ + { + optional: false, + name: 'longitude', + typeAnnotation: { + type: 'NumberTypeAnnotation', + }, + }, + { + optional: false, + name: 'latitude', + typeAnnotation: { + type: 'NumberTypeAnnotation', + }, + }, + { + optional: true, + name: 'altitude', + typeAnnotation: { + type: 'NumberTypeAnnotation', + }, + }, + { + optional: true, + name: 'heading', + typeAnnotation: { + type: 'NumberTypeAnnotation', + }, + }, + { + optional: true, + name: 'speed', + typeAnnotation: { + type: 'NumberTypeAnnotation', + }, + }, + ], + }, + }, + ], + }, + }, + ], + }, + PhotoIdentifiersPage: { + type: 'ObjectTypeAnnotation', + properties: [ + { + optional: false, + name: 'edges', + typeAnnotation: { + type: 'ArrayTypeAnnotation', + elementType: { + type: 'TypeAliasTypeAnnotation', + name: 'PhotoIdentifier', + }, + }, + }, + { + optional: false, + name: 'page_info', + typeAnnotation: { + type: 'ObjectTypeAnnotation', + properties: [ + { + optional: false, + name: 'has_next_page', + typeAnnotation: { + type: 'BooleanTypeAnnotation', + }, + }, + { + optional: true, + name: 'start_cursor', + typeAnnotation: { + type: 'StringTypeAnnotation', + }, + }, + { + optional: true, + name: 'end_cursor', + typeAnnotation: { + type: 'StringTypeAnnotation', + }, + }, + ], + }, + }, + ], + }, + GetPhotosParams: { + type: 'ObjectTypeAnnotation', + properties: [ + { + optional: false, + name: 'first', + typeAnnotation: { + type: 'NumberTypeAnnotation', + }, + }, + { + optional: true, + name: 'after', + typeAnnotation: { + type: 'StringTypeAnnotation', + }, + }, + { + optional: true, + name: 'groupName', + typeAnnotation: { + type: 'StringTypeAnnotation', + }, + }, + { + optional: true, + name: 'groupTypes', + typeAnnotation: { + type: 'StringTypeAnnotation', + }, + }, + { + optional: true, + name: 'assetType', + typeAnnotation: { + type: 'StringTypeAnnotation', + }, + }, + { + optional: true, + name: 'maxSize', + typeAnnotation: { + type: 'NumberTypeAnnotation', + }, + }, + { + optional: true, + name: 'mimeTypes', + typeAnnotation: { + type: 'ArrayTypeAnnotation', + elementType: { + type: 'StringTypeAnnotation', + }, + }, + }, + ], + }, + }, + properties: [ + { + name: 'getConstants', + typeAnnotation: { + type: 'FunctionTypeAnnotation', + returnTypeAnnotation: { + nullable: false, + type: 'ObjectTypeAnnotation', + properties: [], + }, + params: [], + optional: false, + }, + }, + { + name: 'getPhotos', + typeAnnotation: { + type: 'FunctionTypeAnnotation', + returnTypeAnnotation: { + type: 'GenericPromiseTypeAnnotation', + nullable: false, + }, + params: [ + { + nullable: false, + name: 'params', + typeAnnotation: { + type: 'TypeAliasTypeAnnotation', + name: 'GetPhotosParams', + }, + }, + ], + optional: false, + }, + }, + { + name: 'saveToCameraRoll', + typeAnnotation: { + type: 'FunctionTypeAnnotation', + returnTypeAnnotation: { + type: 'GenericPromiseTypeAnnotation', + nullable: false, + }, + params: [ + { + nullable: false, + name: 'uri', + typeAnnotation: { + type: 'StringTypeAnnotation', + }, + }, + { + nullable: false, + name: 'type', + typeAnnotation: { + type: 'StringTypeAnnotation', + }, + }, + ], + optional: false, + }, + }, + { + name: 'deletePhotos', + typeAnnotation: { + type: 'FunctionTypeAnnotation', + returnTypeAnnotation: { + type: 'GenericPromiseTypeAnnotation', + nullable: false, + }, + params: [ + { + name: 'assets', + nullable: false, + typeAnnotation: { + type: 'ArrayTypeAnnotation', + elementType: { + type: 'StringTypeAnnotation', + }, + }, + }, + ], + optional: false, + }, + }, + ], + }, + }, + }, + NativeImagePickerIOS: { + nativeModules: { + ImagePickerIOS: { + aliases: {}, + properties: [ + { + name: 'openCameraDialog', + typeAnnotation: { + type: 'FunctionTypeAnnotation', + returnTypeAnnotation: { + nullable: false, + type: 'VoidTypeAnnotation', + }, + params: [ + { + nullable: false, + name: 'config', + typeAnnotation: { + type: 'ObjectTypeAnnotation', + properties: [ + { + optional: false, + name: 'unmirrorFrontFacingCamera', + typeAnnotation: { + type: 'BooleanTypeAnnotation', + }, + }, + { + optional: false, + name: 'videoMode', + typeAnnotation: { + type: 'BooleanTypeAnnotation', + }, + }, + ], + }, + }, + { + name: 'successCallback', + nullable: false, + typeAnnotation: { + type: 'FunctionTypeAnnotation', + }, + }, + { + name: 'cancelCallback', + nullable: false, + typeAnnotation: { + type: 'FunctionTypeAnnotation', + }, + }, + ], + optional: false, + }, + }, + ], + }, + }, + }, + NativeExceptionsManager: { + nativeModules: { + ExceptionsManager: { + aliases: { + StackFrame: { + properties: [ + { + optional: true, + name: 'column', + typeAnnotation: { + type: 'NumberTypeAnnotation', + }, + }, + { + optional: false, + name: 'file', + typeAnnotation: { + type: 'StringTypeAnnotation', + }, + }, + { + optional: true, + name: 'lineNumber', + typeAnnotation: { + type: 'NumberTypeAnnotation', + }, + }, + { + optional: false, + name: 'methodName', + typeAnnotation: { + type: 'StringTypeAnnotation', + }, + }, + { + optional: true, + name: 'collapse', + typeAnnotation: { + type: 'BooleanTypeAnnotation', + }, + }, + ], + type: 'ObjectTypeAnnotation', + }, + ExceptionData: { + properties: [ + { + optional: false, + name: 'message', + typeAnnotation: { + type: 'StringTypeAnnotation', + }, + }, + { + optional: false, + name: 'originalMessage', + typeAnnotation: { + type: 'StringTypeAnnotation', + }, + }, + { + optional: false, + name: 'name', + typeAnnotation: { + type: 'StringTypeAnnotation', + }, + }, + { + optional: false, + name: 'componentStack', + typeAnnotation: { + type: 'StringTypeAnnotation', + }, + }, + { + optional: false, + name: 'stack', + typeAnnotation: { + type: 'ArrayTypeAnnotation', + elementType: { + type: 'TypeAliasTypeAnnotation', + name: 'StackFrame', + }, + }, + }, + { + optional: false, + name: 'id', + typeAnnotation: { + type: 'NumberTypeAnnotation', + }, + }, + { + optional: false, + name: 'isFatal', + typeAnnotation: { + type: 'BooleanTypeAnnotation', + }, + }, + { + optional: true, + name: 'extraData', + typeAnnotation: { + type: 'GenericObjectTypeAnnotation', + }, + }, + ], + type: 'ObjectTypeAnnotation', + }, + }, + properties: [ + { + name: 'reportFatalException', + typeAnnotation: { + type: 'FunctionTypeAnnotation', + returnTypeAnnotation: { + nullable: false, + type: 'VoidTypeAnnotation', + }, + params: [ + { + nullable: false, + name: 'message', + typeAnnotation: { + type: 'StringTypeAnnotation', + }, + }, + { + name: 'stack', + nullable: false, + typeAnnotation: { + type: 'ArrayTypeAnnotation', + elementType: { + type: 'TypeAliasTypeAnnotation', + name: 'StackFrame', + }, + }, + }, + { + nullable: false, + name: 'exceptionId', + typeAnnotation: { + type: 'NumberTypeAnnotation', + }, + }, + ], + optional: false, + }, + }, + { + name: 'reportSoftException', + typeAnnotation: { + type: 'FunctionTypeAnnotation', + returnTypeAnnotation: { + nullable: false, + type: 'VoidTypeAnnotation', + }, + params: [ + { + nullable: false, + name: 'message', + typeAnnotation: { + type: 'StringTypeAnnotation', + }, + }, + { + name: 'stack', + nullable: false, + typeAnnotation: { + type: 'ArrayTypeAnnotation', + elementType: { + type: 'TypeAliasTypeAnnotation', + name: 'StackFrame', + }, + }, + }, + { + nullable: false, + name: 'exceptionId', + typeAnnotation: { + type: 'NumberTypeAnnotation', + }, + }, + ], + optional: false, + }, + }, + { + name: 'reportException', + typeAnnotation: { + type: 'FunctionTypeAnnotation', + returnTypeAnnotation: { + nullable: false, + type: 'VoidTypeAnnotation', + }, + params: [ + { + nullable: false, + name: 'data', + typeAnnotation: { + type: 'TypeAliasTypeAnnotation', + name: 'ExceptionData', + }, + }, + ], + optional: true, + }, + }, + { + name: 'updateExceptionMessage', + typeAnnotation: { + type: 'FunctionTypeAnnotation', + returnTypeAnnotation: { + nullable: false, + type: 'VoidTypeAnnotation', + }, + params: [ + { + nullable: false, + name: 'message', + typeAnnotation: { + type: 'StringTypeAnnotation', + }, + }, + { + name: 'stack', + nullable: false, + typeAnnotation: { + type: 'ArrayTypeAnnotation', + elementType: { + type: 'TypeAliasTypeAnnotation', + name: 'StackFrame', + }, + }, + }, + { + nullable: false, + name: 'exceptionId', + typeAnnotation: { + type: 'NumberTypeAnnotation', + }, + }, + ], + optional: false, + }, + }, + { + name: 'dismissRedbox', + typeAnnotation: { + type: 'FunctionTypeAnnotation', + returnTypeAnnotation: { + nullable: false, + type: 'VoidTypeAnnotation', + }, + params: [], + optional: true, + }, + }, + ], + }, + }, + }, + }, +}; module.exports = { COMPLEX_OBJECTS, TWO_MODULES_SAME_FILE, TWO_MODULES_DIFFERENT_FILES, EMPTY_NATIVE_MODULES, SIMPLE_NATIVE_MODULES, + NATIVE_MODULES_WITH_TYPE_ALIASES, + REAL_MODULE_EXAMPLE, }; diff --git a/packages/react-native-codegen/src/generators/modules/__test_fixtures__/structFixtures.js b/packages/react-native-codegen/src/generators/modules/__test_fixtures__/structFixtures.js index cbb6fb58ec0..2de452b87c2 100644 --- a/packages/react-native-codegen/src/generators/modules/__test_fixtures__/structFixtures.js +++ b/packages/react-native-codegen/src/generators/modules/__test_fixtures__/structFixtures.js @@ -21,7 +21,7 @@ const SIMPLE_STRUCT: $ReadOnlyArray< |}>, > = [ { - name: 'SampleFuncReturnType', + name: 'SpecSampleFuncReturnType', object: { type: 'ObjectTypeAnnotation', properties: [ @@ -122,7 +122,7 @@ const SIMPLE_CONSTANTS: $ReadOnlyArray< |}>, > = [ { - name: 'GetConstantsReturnType', + name: 'SpecGetConstantsReturnType', object: { type: 'ObjectTypeAnnotation', properties: [ diff --git a/packages/react-native-codegen/src/generators/modules/__tests__/GenerateStructs-test.js b/packages/react-native-codegen/src/generators/modules/__tests__/GenerateStructs-test.js index 4791308f586..a66b5ff7e4c 100644 --- a/packages/react-native-codegen/src/generators/modules/__tests__/GenerateStructs-test.js +++ b/packages/react-native-codegen/src/generators/modules/__tests__/GenerateStructs-test.js @@ -23,7 +23,7 @@ describe('GenerateStructs', () => { it(`can generate fixture ${fixtureName}`, () => { expect( generator - .translateObjectsForStructs(fixture, fixtureName) + .translateObjectsForStructs(fixture, fixtureName, {}) .replace(/::_MODULE_NAME_::/g, 'SampleTurboModule'), ).toMatchSnapshot(); }); diff --git a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleCpp-test.js.snap b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleCpp-test.js.snap index be5e11a7f90..d55f56b4b57 100644 --- a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleCpp-test.js.snap +++ b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleCpp-test.js.snap @@ -72,6 +72,130 @@ NativeSampleTurboModuleCxxSpecJSI::NativeSampleTurboModuleCxxSpecJSI(std::shared } +} // namespace react +} // namespace facebook +", +} +`; + +exports[`GenerateModuleCpp can generate fixture NATIVE_MODULES_WITH_TYPE_ALIASES 1`] = ` +Map { + "NativeModules.cpp" => " +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include + +namespace facebook { +namespace react { + +static jsi::Value __hostFunction_NativeAliasTurboModuleCxxSpecJSI_getConstants(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->getConstants(rt); +} + +static jsi::Value __hostFunction_NativeAliasTurboModuleCxxSpecJSI_cropImage(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + static_cast(&turboModule)->cropImage(rt, args[0].getObject(rt)); + return jsi::Value::undefined(); +} + +NativeAliasTurboModuleCxxSpecJSI::NativeAliasTurboModuleCxxSpecJSI(std::shared_ptr jsInvoker) + : TurboModule(\\"AliasTurboModule\\", jsInvoker) { + methodMap_[\\"getConstants\\"] = MethodMetadata {0, __hostFunction_NativeAliasTurboModuleCxxSpecJSI_getConstants}; + methodMap_[\\"cropImage\\"] = MethodMetadata {1, __hostFunction_NativeAliasTurboModuleCxxSpecJSI_cropImage}; +} + + +} // namespace react +} // namespace facebook +", +} +`; + +exports[`GenerateModuleCpp can generate fixture REAL_MODULE_EXAMPLE 1`] = ` +Map { + "NativeModules.cpp" => " +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include + +namespace facebook { +namespace react { + +static jsi::Value __hostFunction_NativeCameraRollManagerCxxSpecJSI_getConstants(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->getConstants(rt); +} +static jsi::Value __hostFunction_NativeCameraRollManagerCxxSpecJSI_getPhotos(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->getPhotos(rt, args[0].getObject(rt)); +} +static jsi::Value __hostFunction_NativeCameraRollManagerCxxSpecJSI_saveToCameraRoll(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->saveToCameraRoll(rt, args[0].getString(rt), args[1].getString(rt)); +} +static jsi::Value __hostFunction_NativeCameraRollManagerCxxSpecJSI_deletePhotos(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->deletePhotos(rt, args[0].getObject(rt).getArray(rt)); +} + +NativeCameraRollManagerCxxSpecJSI::NativeCameraRollManagerCxxSpecJSI(std::shared_ptr jsInvoker) + : TurboModule(\\"CameraRollManager\\", jsInvoker) { + methodMap_[\\"getConstants\\"] = MethodMetadata {0, __hostFunction_NativeCameraRollManagerCxxSpecJSI_getConstants}; + methodMap_[\\"getPhotos\\"] = MethodMetadata {1, __hostFunction_NativeCameraRollManagerCxxSpecJSI_getPhotos}; + methodMap_[\\"saveToCameraRoll\\"] = MethodMetadata {2, __hostFunction_NativeCameraRollManagerCxxSpecJSI_saveToCameraRoll}; + methodMap_[\\"deletePhotos\\"] = MethodMetadata {1, __hostFunction_NativeCameraRollManagerCxxSpecJSI_deletePhotos}; +} + +static jsi::Value __hostFunction_NativeImagePickerIOSCxxSpecJSI_openCameraDialog(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + static_cast(&turboModule)->openCameraDialog(rt, args[0].getObject(rt), std::move(args[1].getObject(rt).getFunction(rt)), std::move(args[2].getObject(rt).getFunction(rt))); + return jsi::Value::undefined(); +} + +NativeImagePickerIOSCxxSpecJSI::NativeImagePickerIOSCxxSpecJSI(std::shared_ptr jsInvoker) + : TurboModule(\\"ImagePickerIOS\\", jsInvoker) { + methodMap_[\\"openCameraDialog\\"] = MethodMetadata {3, __hostFunction_NativeImagePickerIOSCxxSpecJSI_openCameraDialog}; +} + +static jsi::Value __hostFunction_NativeExceptionsManagerCxxSpecJSI_reportFatalException(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + static_cast(&turboModule)->reportFatalException(rt, args[0].getString(rt), args[1].getObject(rt).getArray(rt), args[2].getNumber()); + return jsi::Value::undefined(); +} + +static jsi::Value __hostFunction_NativeExceptionsManagerCxxSpecJSI_reportSoftException(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + static_cast(&turboModule)->reportSoftException(rt, args[0].getString(rt), args[1].getObject(rt).getArray(rt), args[2].getNumber()); + return jsi::Value::undefined(); +} + +static jsi::Value __hostFunction_NativeExceptionsManagerCxxSpecJSI_reportException(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + static_cast(&turboModule)->reportException(rt, args[0].getObject(rt)); + return jsi::Value::undefined(); +} + +static jsi::Value __hostFunction_NativeExceptionsManagerCxxSpecJSI_updateExceptionMessage(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + static_cast(&turboModule)->updateExceptionMessage(rt, args[0].getString(rt), args[1].getObject(rt).getArray(rt), args[2].getNumber()); + return jsi::Value::undefined(); +} + +static jsi::Value __hostFunction_NativeExceptionsManagerCxxSpecJSI_dismissRedbox(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + static_cast(&turboModule)->dismissRedbox(rt); + return jsi::Value::undefined(); +} + +NativeExceptionsManagerCxxSpecJSI::NativeExceptionsManagerCxxSpecJSI(std::shared_ptr jsInvoker) + : TurboModule(\\"ExceptionsManager\\", jsInvoker) { + methodMap_[\\"reportFatalException\\"] = MethodMetadata {3, __hostFunction_NativeExceptionsManagerCxxSpecJSI_reportFatalException}; + methodMap_[\\"reportSoftException\\"] = MethodMetadata {3, __hostFunction_NativeExceptionsManagerCxxSpecJSI_reportSoftException}; + methodMap_[\\"reportException\\"] = MethodMetadata {1, __hostFunction_NativeExceptionsManagerCxxSpecJSI_reportException}; + methodMap_[\\"updateExceptionMessage\\"] = MethodMetadata {3, __hostFunction_NativeExceptionsManagerCxxSpecJSI_updateExceptionMessage}; + methodMap_[\\"dismissRedbox\\"] = MethodMetadata {0, __hostFunction_NativeExceptionsManagerCxxSpecJSI_dismissRedbox}; +} + + } // namespace react } // namespace facebook ", diff --git a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleH-test.js.snap b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleH-test.js.snap index 8a4271cb020..bda31d0a36e 100644 --- a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleH-test.js.snap +++ b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleH-test.js.snap @@ -59,6 +59,96 @@ protected: public: +}; + +} // namespace react +} // namespace facebook +", +} +`; + +exports[`GenerateModuleCpp can generate fixture NATIVE_MODULES_WITH_TYPE_ALIASES 1`] = ` +Map { + "NativeModules.h" => " +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include + +namespace facebook { +namespace react { + +class JSI_EXPORT NativeAliasTurboModuleCxxSpecJSI : public TurboModule { +protected: + NativeAliasTurboModuleCxxSpecJSI(std::shared_ptr jsInvoker); + +public: +virtual jsi::Object getConstants(jsi::Runtime &rt) = 0; +virtual void cropImage(jsi::Runtime &rt, const jsi::Object &cropData) = 0; + +}; + +} // namespace react +} // namespace facebook +", +} +`; + +exports[`GenerateModuleCpp can generate fixture REAL_MODULE_EXAMPLE 1`] = ` +Map { + "NativeModules.h" => " +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include + +namespace facebook { +namespace react { + +class JSI_EXPORT NativeCameraRollManagerCxxSpecJSI : public TurboModule { +protected: + NativeCameraRollManagerCxxSpecJSI(std::shared_ptr jsInvoker); + +public: +virtual jsi::Object getConstants(jsi::Runtime &rt) = 0; +virtual jsi::Value getPhotos(jsi::Runtime &rt, const jsi::Object ¶ms) = 0; +virtual jsi::Value saveToCameraRoll(jsi::Runtime &rt, const jsi::String &uri, const jsi::String &type) = 0; +virtual jsi::Value deletePhotos(jsi::Runtime &rt, const jsi::Array &assets) = 0; + +}; + +class JSI_EXPORT NativeImagePickerIOSCxxSpecJSI : public TurboModule { +protected: + NativeImagePickerIOSCxxSpecJSI(std::shared_ptr jsInvoker); + +public: +virtual void openCameraDialog(jsi::Runtime &rt, const jsi::Object &config, const jsi::Function &successCallback, const jsi::Function &cancelCallback) = 0; + +}; + +class JSI_EXPORT NativeExceptionsManagerCxxSpecJSI : public TurboModule { +protected: + NativeExceptionsManagerCxxSpecJSI(std::shared_ptr jsInvoker); + +public: +virtual void reportFatalException(jsi::Runtime &rt, const jsi::String &message, const jsi::Array &stack, double exceptionId) = 0; +virtual void reportSoftException(jsi::Runtime &rt, const jsi::String &message, const jsi::Array &stack, double exceptionId) = 0; +virtual void reportException(jsi::Runtime &rt, const jsi::Object &data) = 0; +virtual void updateExceptionMessage(jsi::Runtime &rt, const jsi::String &message, const jsi::Array &stack, double exceptionId) = 0; +virtual void dismissRedbox(jsi::Runtime &rt) = 0; + }; } // namespace react diff --git a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleHObjCpp-test.js.snap b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleHObjCpp-test.js.snap index 0d92adac32c..939b9bcea8d 100644 --- a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleHObjCpp-test.js.snap +++ b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleHObjCpp-test.js.snap @@ -96,7 +96,7 @@ namespace JS { folly::Optional> optionalArrayOfNumbers() const; facebook::react::LazyVector arrayOfStrings() const; folly::Optional> optionalArrayOfStrings() const; - facebook::react::LazyVector arrayOfObjects() const; + facebook::react::LazyVector arrayOfObjects() const; SpecGetArraysOptions(NSDictionary *const v) : _v(v) {} private: @@ -305,10 +305,10 @@ inline folly::Optional> JS::NativeSample } -inline facebook::react::LazyVector JS::NativeSampleTurboModule::SpecGetArraysOptions::arrayOfObjects() const +inline facebook::react::LazyVector JS::NativeSampleTurboModule::SpecGetArraysOptions::arrayOfObjects() const { id const p = _v[@\\"arrayOfObjects\\"]; - return RCTBridgingToVec(p, ^JS::NativeSampleTurboModule::SpecGetArraysOptionsArrayOfObjectsElement(id itemValue_0) { return JS::NativeSampleTurboModule::SpecGetArraysOptionsArrayOfObjectsElement(itemValue_0); }); + return RCTBridgingToVec(p, ^JS::NativeSampleTurboModule::arrayOfObjectsElement(id itemValue_0) { return JS::NativeSampleTurboModule::arrayOfObjectsElement(itemValue_0); }); } @@ -363,12 +363,12 @@ inline double JS::NativeSampleTurboModule::SpecOptionalsAOptionalObjectProperty: @protocol NativeSampleTurboModuleSpec -- (NSDictionary *) difficult:(JS::NativeSampleTurboModule::SpecDifficultA&)A; -- (void) optionals:(JS::NativeSampleTurboModule::SpecOptionalsA&)A; +- (NSDictionary *) difficult:(JS::NativeSampleTurboModule::SpecDifficultA &)A; +- (void) optionals:(JS::NativeSampleTurboModule::SpecOptionalsA &)A; - (void) optionalMethod:(NSDictionary *)options callback:(RCTResponseSenderBlock)callback extras:(NSArray * _Nullable)extras; -- (void) getArrays:(JS::NativeSampleTurboModule::SpecGetArraysOptions&)options; +- (void) getArrays:(JS::NativeSampleTurboModule::SpecGetArraysOptions &)options; @end @@ -443,6 +443,827 @@ namespace facebook { } `; +exports[`GenerateModuleHObjCpp can generate fixture NATIVE_MODULES_WITH_TYPE_ALIASES 1`] = ` +Map { + "SampleSpec.h" => " +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @generated by codegen project: GenerateModuleHObjCpp.js + */ + +#ifndef __cplusplus +#error This file must be compiled as Obj-C++. If you are importing it, you must change your file extension to .mm. +#endif + +#import + +#import + +#import + +#import +#import +#import + +#import +#import +#import + +#import + + + +namespace JS { + namespace NativeAliasTurboModule { + struct OptionsDisplaySize { + double width() const; + double height() const; + + OptionsDisplaySize(NSDictionary *const v) : _v(v) {} + private: + NSDictionary *_v; + }; + } +} + +@interface RCTCxxConvert (NativeAliasTurboModule_OptionsDisplaySize) ++ (RCTManagedPointer *)JS_NativeAliasTurboModule_OptionsDisplaySize:(id)json; +@end + + +namespace JS { + namespace NativeAliasTurboModule { + struct OptionsSize { + double width() const; + double height() const; + + OptionsSize(NSDictionary *const v) : _v(v) {} + private: + NSDictionary *_v; + }; + } +} + +@interface RCTCxxConvert (NativeAliasTurboModule_OptionsSize) ++ (RCTManagedPointer *)JS_NativeAliasTurboModule_OptionsSize:(id)json; +@end + + +namespace JS { + namespace NativeAliasTurboModule { + struct OptionsOffset { + double x() const; + double y() const; + + OptionsOffset(NSDictionary *const v) : _v(v) {} + private: + NSDictionary *_v; + }; + } +} + +@interface RCTCxxConvert (NativeAliasTurboModule_OptionsOffset) ++ (RCTManagedPointer *)JS_NativeAliasTurboModule_OptionsOffset:(id)json; +@end + + +namespace JS { + namespace NativeAliasTurboModule { + struct Options { + JS::NativeAliasTurboModule::OptionsOffset offset() const; + JS::NativeAliasTurboModule::OptionsSize size() const; + folly::Optional displaySize() const; + NSString *resizeMode() const; + folly::Optional allowExternalStorage() const; + + Options(NSDictionary *const v) : _v(v) {} + private: + NSDictionary *_v; + }; + } +} + +@interface RCTCxxConvert (NativeAliasTurboModule_Options) ++ (RCTManagedPointer *)JS_NativeAliasTurboModule_Options:(id)json; +@end + +inline JS::NativeAliasTurboModule::OptionsOffset JS::NativeAliasTurboModule::Options::offset() const +{ + id const p = _v[@\\"offset\\"]; + return JS::NativeAliasTurboModule::OptionsOffset(p); +} + + +inline JS::NativeAliasTurboModule::OptionsSize JS::NativeAliasTurboModule::Options::size() const +{ + id const p = _v[@\\"size\\"]; + return JS::NativeAliasTurboModule::OptionsSize(p); +} + + +inline folly::Optional JS::NativeAliasTurboModule::Options::displaySize() const +{ + id const p = _v[@\\"displaySize\\"]; + return (p == nil ? folly::none : folly::make_optional(JS::NativeAliasTurboModule::OptionsDisplaySize(p))); +} + + +inline NSString *JS::NativeAliasTurboModule::Options::resizeMode() const +{ + id const p = _v[@\\"resizeMode\\"]; + return RCTBridgingToString(p); +} + + +inline folly::Optional JS::NativeAliasTurboModule::Options::allowExternalStorage() const +{ + id const p = _v[@\\"allowExternalStorage\\"]; + return RCTBridgingToOptionalBool(p); +} + + +inline double JS::NativeAliasTurboModule::OptionsOffset::x() const +{ + id const p = _v[@\\"x\\"]; + return RCTBridgingToDouble(p); +} + + +inline double JS::NativeAliasTurboModule::OptionsOffset::y() const +{ + id const p = _v[@\\"y\\"]; + return RCTBridgingToDouble(p); +} + + +inline double JS::NativeAliasTurboModule::OptionsSize::width() const +{ + id const p = _v[@\\"width\\"]; + return RCTBridgingToDouble(p); +} + + +inline double JS::NativeAliasTurboModule::OptionsSize::height() const +{ + id const p = _v[@\\"height\\"]; + return RCTBridgingToDouble(p); +} + + +inline double JS::NativeAliasTurboModule::OptionsDisplaySize::width() const +{ + id const p = _v[@\\"width\\"]; + return RCTBridgingToDouble(p); +} + + +inline double JS::NativeAliasTurboModule::OptionsDisplaySize::height() const +{ + id const p = _v[@\\"height\\"]; + return RCTBridgingToDouble(p); +} + + + +@protocol NativeAliasTurboModuleSpec + +- (void) cropImage:(JS::NativeAliasTurboModule::Options &)cropData; +@end + + +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'AliasTurboModule' + */ + class JSI_EXPORT NativeAliasTurboModuleSpecJSI : public ObjCTurboModule { + public: + NativeAliasTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react +} // namespace facebook +", +} +`; + +exports[`GenerateModuleHObjCpp can generate fixture REAL_MODULE_EXAMPLE 1`] = ` +Map { + "SampleSpec.h" => " +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @generated by codegen project: GenerateModuleHObjCpp.js + */ + +#ifndef __cplusplus +#error This file must be compiled as Obj-C++. If you are importing it, you must change your file extension to .mm. +#endif + +#import + +#import + +#import + +#import +#import +#import + +#import +#import +#import + +#import + + + +namespace JS { + namespace NativeCameraRollManager { + struct PhotoIdentifierNodeLocation { + double longitude() const; + double latitude() const; + folly::Optional altitude() const; + folly::Optional heading() const; + folly::Optional speed() const; + + PhotoIdentifierNodeLocation(NSDictionary *const v) : _v(v) {} + private: + NSDictionary *_v; + }; + } +} + +@interface RCTCxxConvert (NativeCameraRollManager_PhotoIdentifierNodeLocation) ++ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifierNodeLocation:(id)json; +@end + + +namespace JS { + namespace NativeCameraRollManager { + struct PhotoIdentifierNode { + JS::NativeCameraRollManager::PhotoIdentifierImage image() const; + NSString *type() const; + NSString *group_name() const; + double timestamp() const; + JS::NativeCameraRollManager::PhotoIdentifierNodeLocation location() const; + + PhotoIdentifierNode(NSDictionary *const v) : _v(v) {} + private: + NSDictionary *_v; + }; + } +} + +@interface RCTCxxConvert (NativeCameraRollManager_PhotoIdentifierNode) ++ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifierNode:(id)json; +@end + + +namespace JS { + namespace NativeCameraRollManager { + struct PhotoIdentifiersPagePage_info { + bool has_next_page() const; + NSString *start_cursor() const; + NSString *end_cursor() const; + + PhotoIdentifiersPagePage_info(NSDictionary *const v) : _v(v) {} + private: + NSDictionary *_v; + }; + } +} + +@interface RCTCxxConvert (NativeCameraRollManager_PhotoIdentifiersPagePage_info) ++ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifiersPagePage_info:(id)json; +@end + + +namespace JS { + namespace NativeCameraRollManager { + struct PhotoIdentifierImage { + NSString *uri() const; + double playableDuration() const; + double width() const; + double height() const; + folly::Optional isStored() const; + NSString *filename() const; + + PhotoIdentifierImage(NSDictionary *const v) : _v(v) {} + private: + NSDictionary *_v; + }; + } +} + +@interface RCTCxxConvert (NativeCameraRollManager_PhotoIdentifierImage) ++ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifierImage:(id)json; +@end + + +namespace JS { + namespace NativeCameraRollManager { + struct PhotoIdentifier { + JS::NativeCameraRollManager::PhotoIdentifierNode node() const; + + PhotoIdentifier(NSDictionary *const v) : _v(v) {} + private: + NSDictionary *_v; + }; + } +} + +@interface RCTCxxConvert (NativeCameraRollManager_PhotoIdentifier) ++ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifier:(id)json; +@end + + +namespace JS { + namespace NativeCameraRollManager { + struct PhotoIdentifiersPage { + facebook::react::LazyVector edges() const; + JS::NativeCameraRollManager::PhotoIdentifiersPagePage_info page_info() const; + + PhotoIdentifiersPage(NSDictionary *const v) : _v(v) {} + private: + NSDictionary *_v; + }; + } +} + +@interface RCTCxxConvert (NativeCameraRollManager_PhotoIdentifiersPage) ++ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifiersPage:(id)json; +@end + + +namespace JS { + namespace NativeCameraRollManager { + struct GetPhotosParams { + double first() const; + NSString *after() const; + NSString *groupName() const; + NSString *groupTypes() const; + NSString *assetType() const; + folly::Optional maxSize() const; + folly::Optional> mimeTypes() const; + + GetPhotosParams(NSDictionary *const v) : _v(v) {} + private: + NSDictionary *_v; + }; + } +} + +@interface RCTCxxConvert (NativeCameraRollManager_GetPhotosParams) ++ (RCTManagedPointer *)JS_NativeCameraRollManager_GetPhotosParams:(id)json; +@end + +inline double JS::NativeCameraRollManager::GetPhotosParams::first() const +{ + id const p = _v[@\\"first\\"]; + return RCTBridgingToDouble(p); +} + + +inline NSString *JS::NativeCameraRollManager::GetPhotosParams::after() const +{ + id const p = _v[@\\"after\\"]; + return RCTBridgingToString(p); +} + + +inline NSString *JS::NativeCameraRollManager::GetPhotosParams::groupName() const +{ + id const p = _v[@\\"groupName\\"]; + return RCTBridgingToString(p); +} + + +inline NSString *JS::NativeCameraRollManager::GetPhotosParams::groupTypes() const +{ + id const p = _v[@\\"groupTypes\\"]; + return RCTBridgingToString(p); +} + + +inline NSString *JS::NativeCameraRollManager::GetPhotosParams::assetType() const +{ + id const p = _v[@\\"assetType\\"]; + return RCTBridgingToString(p); +} + + +inline folly::Optional JS::NativeCameraRollManager::GetPhotosParams::maxSize() const +{ + id const p = _v[@\\"maxSize\\"]; + return RCTBridgingToOptionalDouble(p); +} + + +inline folly::Optional> JS::NativeCameraRollManager::GetPhotosParams::mimeTypes() const +{ + id const p = _v[@\\"mimeTypes\\"]; + return RCTBridgingToOptionalVec(p, ^NSString *(id itemValue_0) { return RCTBridgingToString(itemValue_0); }); +} + + +inline facebook::react::LazyVector JS::NativeCameraRollManager::PhotoIdentifiersPage::edges() const +{ + id const p = _v[@\\"edges\\"]; + return RCTBridgingToVec(p, ^JS::NativeCameraRollManager::PhotoIdentifier(id itemValue_0) { return JS::NativeCameraRollManager::PhotoIdentifier(itemValue_0); }); +} + + +inline JS::NativeCameraRollManager::PhotoIdentifiersPagePage_info JS::NativeCameraRollManager::PhotoIdentifiersPage::page_info() const +{ + id const p = _v[@\\"page_info\\"]; + return JS::NativeCameraRollManager::PhotoIdentifiersPagePage_info(p); +} + + +inline JS::NativeCameraRollManager::PhotoIdentifierNode JS::NativeCameraRollManager::PhotoIdentifier::node() const +{ + id const p = _v[@\\"node\\"]; + return JS::NativeCameraRollManager::PhotoIdentifierNode(p); +} + + +inline NSString *JS::NativeCameraRollManager::PhotoIdentifierImage::uri() const +{ + id const p = _v[@\\"uri\\"]; + return RCTBridgingToString(p); +} + + +inline double JS::NativeCameraRollManager::PhotoIdentifierImage::playableDuration() const +{ + id const p = _v[@\\"playableDuration\\"]; + return RCTBridgingToDouble(p); +} + + +inline double JS::NativeCameraRollManager::PhotoIdentifierImage::width() const +{ + id const p = _v[@\\"width\\"]; + return RCTBridgingToDouble(p); +} + + +inline double JS::NativeCameraRollManager::PhotoIdentifierImage::height() const +{ + id const p = _v[@\\"height\\"]; + return RCTBridgingToDouble(p); +} + + +inline folly::Optional JS::NativeCameraRollManager::PhotoIdentifierImage::isStored() const +{ + id const p = _v[@\\"isStored\\"]; + return RCTBridgingToOptionalBool(p); +} + + +inline NSString *JS::NativeCameraRollManager::PhotoIdentifierImage::filename() const +{ + id const p = _v[@\\"filename\\"]; + return RCTBridgingToString(p); +} + + +inline bool JS::NativeCameraRollManager::PhotoIdentifiersPagePage_info::has_next_page() const +{ + id const p = _v[@\\"has_next_page\\"]; + return RCTBridgingToBool(p); +} + + +inline NSString *JS::NativeCameraRollManager::PhotoIdentifiersPagePage_info::start_cursor() const +{ + id const p = _v[@\\"start_cursor\\"]; + return RCTBridgingToString(p); +} + + +inline NSString *JS::NativeCameraRollManager::PhotoIdentifiersPagePage_info::end_cursor() const +{ + id const p = _v[@\\"end_cursor\\"]; + return RCTBridgingToString(p); +} + + +inline JS::NativeCameraRollManager::PhotoIdentifierImage JS::NativeCameraRollManager::PhotoIdentifierNode::image() const +{ + id const p = _v[@\\"image\\"]; + return JS::NativeCameraRollManager::PhotoIdentifierImage(p); +} + + +inline NSString *JS::NativeCameraRollManager::PhotoIdentifierNode::type() const +{ + id const p = _v[@\\"type\\"]; + return RCTBridgingToString(p); +} + + +inline NSString *JS::NativeCameraRollManager::PhotoIdentifierNode::group_name() const +{ + id const p = _v[@\\"group_name\\"]; + return RCTBridgingToString(p); +} + + +inline double JS::NativeCameraRollManager::PhotoIdentifierNode::timestamp() const +{ + id const p = _v[@\\"timestamp\\"]; + return RCTBridgingToDouble(p); +} + + +inline JS::NativeCameraRollManager::PhotoIdentifierNodeLocation JS::NativeCameraRollManager::PhotoIdentifierNode::location() const +{ + id const p = _v[@\\"location\\"]; + return JS::NativeCameraRollManager::PhotoIdentifierNodeLocation(p); +} + + +inline double JS::NativeCameraRollManager::PhotoIdentifierNodeLocation::longitude() const +{ + id const p = _v[@\\"longitude\\"]; + return RCTBridgingToDouble(p); +} + + +inline double JS::NativeCameraRollManager::PhotoIdentifierNodeLocation::latitude() const +{ + id const p = _v[@\\"latitude\\"]; + return RCTBridgingToDouble(p); +} + + +inline folly::Optional JS::NativeCameraRollManager::PhotoIdentifierNodeLocation::altitude() const +{ + id const p = _v[@\\"altitude\\"]; + return RCTBridgingToOptionalDouble(p); +} + + +inline folly::Optional JS::NativeCameraRollManager::PhotoIdentifierNodeLocation::heading() const +{ + id const p = _v[@\\"heading\\"]; + return RCTBridgingToOptionalDouble(p); +} + + +inline folly::Optional JS::NativeCameraRollManager::PhotoIdentifierNodeLocation::speed() const +{ + id const p = _v[@\\"speed\\"]; + return RCTBridgingToOptionalDouble(p); +} + + + +@protocol NativeCameraRollManagerSpec + +- (void) getPhotos:(JS::NativeCameraRollManager::GetPhotosParams &)params + resolve:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject; +- (void) saveToCameraRoll:(NSString *)uri + type:(NSString *)type + resolve:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject; +- (void) deletePhotos:(NSArray *)assets + resolve:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject; +@end + + + +namespace JS { + namespace NativeExceptionsManager { + struct StackFrame { + folly::Optional column() const; + NSString *file() const; + folly::Optional lineNumber() const; + NSString *methodName() const; + folly::Optional collapse() const; + + StackFrame(NSDictionary *const v) : _v(v) {} + private: + NSDictionary *_v; + }; + } +} + +@interface RCTCxxConvert (NativeExceptionsManager_StackFrame) ++ (RCTManagedPointer *)JS_NativeExceptionsManager_StackFrame:(id)json; +@end + + +namespace JS { + namespace NativeExceptionsManager { + struct ExceptionData { + NSString *message() const; + NSString *originalMessage() const; + NSString *name() const; + NSString *componentStack() const; + facebook::react::LazyVector stack() const; + double id_() const; + bool isFatal() const; + id _Nullable extraData() const; + + ExceptionData(NSDictionary *const v) : _v(v) {} + private: + NSDictionary *_v; + }; + } +} + +@interface RCTCxxConvert (NativeExceptionsManager_ExceptionData) ++ (RCTManagedPointer *)JS_NativeExceptionsManager_ExceptionData:(id)json; +@end + +inline NSString *JS::NativeExceptionsManager::ExceptionData::message() const +{ + id const p = _v[@\\"message\\"]; + return RCTBridgingToString(p); +} + + +inline NSString *JS::NativeExceptionsManager::ExceptionData::originalMessage() const +{ + id const p = _v[@\\"originalMessage\\"]; + return RCTBridgingToString(p); +} + + +inline NSString *JS::NativeExceptionsManager::ExceptionData::name() const +{ + id const p = _v[@\\"name\\"]; + return RCTBridgingToString(p); +} + + +inline NSString *JS::NativeExceptionsManager::ExceptionData::componentStack() const +{ + id const p = _v[@\\"componentStack\\"]; + return RCTBridgingToString(p); +} + + +inline facebook::react::LazyVector JS::NativeExceptionsManager::ExceptionData::stack() const +{ + id const p = _v[@\\"stack\\"]; + return RCTBridgingToVec(p, ^JS::NativeExceptionsManager::StackFrame(id itemValue_0) { return JS::NativeExceptionsManager::StackFrame(itemValue_0); }); +} + + +inline double JS::NativeExceptionsManager::ExceptionData::id_() const +{ + id const p = _v[@\\"id_\\"]; + return RCTBridgingToDouble(p); +} + + +inline bool JS::NativeExceptionsManager::ExceptionData::isFatal() const +{ + id const p = _v[@\\"isFatal\\"]; + return RCTBridgingToBool(p); +} + + +inline id _Nullable JS::NativeExceptionsManager::ExceptionData::extraData() const +{ + id const p = _v[@\\"extraData\\"]; + return p; +} + + +inline folly::Optional JS::NativeExceptionsManager::StackFrame::column() const +{ + id const p = _v[@\\"column\\"]; + return RCTBridgingToOptionalDouble(p); +} + + +inline NSString *JS::NativeExceptionsManager::StackFrame::file() const +{ + id const p = _v[@\\"file\\"]; + return RCTBridgingToString(p); +} + + +inline folly::Optional JS::NativeExceptionsManager::StackFrame::lineNumber() const +{ + id const p = _v[@\\"lineNumber\\"]; + return RCTBridgingToOptionalDouble(p); +} + + +inline NSString *JS::NativeExceptionsManager::StackFrame::methodName() const +{ + id const p = _v[@\\"methodName\\"]; + return RCTBridgingToString(p); +} + + +inline folly::Optional JS::NativeExceptionsManager::StackFrame::collapse() const +{ + id const p = _v[@\\"collapse\\"]; + return RCTBridgingToOptionalBool(p); +} + + + +@protocol NativeExceptionsManagerSpec +- (void) reportFatalException:(NSString *)message + stack:(NSArray *)stack + exceptionId:(double)exceptionId; +- (void) reportSoftException:(NSString *)message + stack:(NSArray *)stack + exceptionId:(double)exceptionId; +- (void) reportException:(JS::NativeExceptionsManager::ExceptionData &)data; +- (void) updateExceptionMessage:(NSString *)message + stack:(NSArray *)stack + exceptionId:(double)exceptionId; +- (void) dismissRedbox; +@end + + + +namespace JS { + namespace NativeImagePickerIOS { + struct SpecOpenCameraDialogConfig { + bool unmirrorFrontFacingCamera() const; + bool videoMode() const; + + SpecOpenCameraDialogConfig(NSDictionary *const v) : _v(v) {} + private: + NSDictionary *_v; + }; + } +} + +@interface RCTCxxConvert (NativeImagePickerIOS_SpecOpenCameraDialogConfig) ++ (RCTManagedPointer *)JS_NativeImagePickerIOS_SpecOpenCameraDialogConfig:(id)json; +@end + +inline bool JS::NativeImagePickerIOS::SpecOpenCameraDialogConfig::unmirrorFrontFacingCamera() const +{ + id const p = _v[@\\"unmirrorFrontFacingCamera\\"]; + return RCTBridgingToBool(p); +} + + +inline bool JS::NativeImagePickerIOS::SpecOpenCameraDialogConfig::videoMode() const +{ + id const p = _v[@\\"videoMode\\"]; + return RCTBridgingToBool(p); +} + + + +@protocol NativeImagePickerIOSSpec +- (void) openCameraDialog:(JS::NativeImagePickerIOS::SpecOpenCameraDialogConfig &)config + successCallback:(RCTResponseSenderBlock)successCallback + cancelCallback:(RCTResponseSenderBlock)cancelCallback; +@end + + +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'CameraRollManager' + */ + class JSI_EXPORT NativeCameraRollManagerSpecJSI : public ObjCTurboModule { + public: + NativeCameraRollManagerSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + /** + * ObjC++ class for module 'ExceptionsManager' + */ + class JSI_EXPORT NativeExceptionsManagerSpecJSI : public ObjCTurboModule { + public: + NativeExceptionsManagerSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + /** + * ObjC++ class for module 'ImagePickerIOS' + */ + class JSI_EXPORT NativeImagePickerIOSSpecJSI : public ObjCTurboModule { + public: + NativeImagePickerIOSSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react +} // namespace facebook +", +} +`; + exports[`GenerateModuleHObjCpp can generate fixture SIMPLE_NATIVE_MODULES 1`] = ` Map { "SampleSpec.h" => " diff --git a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleMm-test.js.snap b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleMm-test.js.snap index 3a278d825a7..6192444e427 100644 --- a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleMm-test.js.snap +++ b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleMm-test.js.snap @@ -132,6 +132,248 @@ namespace facebook { } `; +exports[`GenerateModuleHObjCpp can generate fixture NATIVE_MODULES_WITH_TYPE_ALIASES 1`] = ` +Map { + "SampleSpec-generated.mm" => " +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @generated by codegen project: GenerateModuleMm.js + */ + +#include +#import + + +@implementation RCTCxxConvert (NativeAliasTurboModule_Options) ++ (RCTManagedPointer *)JS_NativeAliasTurboModule_Options:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + + +@implementation RCTCxxConvert (NativeAliasTurboModule_OptionsOffset) ++ (RCTManagedPointer *)JS_NativeAliasTurboModule_OptionsOffset:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + + +@implementation RCTCxxConvert (NativeAliasTurboModule_OptionsSize) ++ (RCTManagedPointer *)JS_NativeAliasTurboModule_OptionsSize:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + + +@implementation RCTCxxConvert (NativeAliasTurboModule_OptionsDisplaySize) ++ (RCTManagedPointer *)JS_NativeAliasTurboModule_OptionsDisplaySize:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + +namespace facebook { + namespace react { + + + static facebook::jsi::Value __hostFunction_NativeAliasTurboModuleSpecJSI_cropImage(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule) + .invokeObjCMethod(rt, VoidKind, \\"cropImage\\", @selector(cropImage:), args, count); + } + + NativeAliasTurboModuleSpecJSI::NativeAliasTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) + : ObjCTurboModule(params) { + + methodMap_[\\"cropImage\\"] = MethodMetadata {1, __hostFunction_NativeAliasTurboModuleSpecJSI_cropImage}; + setMethodArgConversionSelector(@\\"cropImage\\", 0, @\\"JS_NativeAliasTurboModule_Options:\\"); + } + } // namespace react +} // namespace facebook +", +} +`; + +exports[`GenerateModuleHObjCpp can generate fixture REAL_MODULE_EXAMPLE 1`] = ` +Map { + "SampleSpec-generated.mm" => " +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @generated by codegen project: GenerateModuleMm.js + */ + +#include +#import + + +@implementation RCTCxxConvert (NativeCameraRollManager_PhotoIdentifierImage) ++ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifierImage:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + + +@implementation RCTCxxConvert (NativeCameraRollManager_PhotoIdentifier) ++ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifier:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + + +@implementation RCTCxxConvert (NativeCameraRollManager_PhotoIdentifiersPage) ++ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifiersPage:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + + +@implementation RCTCxxConvert (NativeCameraRollManager_GetPhotosParams) ++ (RCTManagedPointer *)JS_NativeCameraRollManager_GetPhotosParams:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + + +@implementation RCTCxxConvert (NativeCameraRollManager_PhotoIdentifierNode) ++ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifierNode:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + + +@implementation RCTCxxConvert (NativeCameraRollManager_PhotoIdentifiersPagePage_info) ++ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifiersPagePage_info:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + + +@implementation RCTCxxConvert (NativeCameraRollManager_PhotoIdentifierNodeLocation) ++ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifierNodeLocation:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + + +@implementation RCTCxxConvert (NativeImagePickerIOS_SpecOpenCameraDialogConfig) ++ (RCTManagedPointer *)JS_NativeImagePickerIOS_SpecOpenCameraDialogConfig:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + + +@implementation RCTCxxConvert (NativeExceptionsManager_StackFrame) ++ (RCTManagedPointer *)JS_NativeExceptionsManager_StackFrame:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + + +@implementation RCTCxxConvert (NativeExceptionsManager_ExceptionData) ++ (RCTManagedPointer *)JS_NativeExceptionsManager_ExceptionData:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + +namespace facebook { + namespace react { + + + static facebook::jsi::Value __hostFunction_NativeCameraRollManagerSpecJSI_getPhotos(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule) + .invokeObjCMethod(rt, PromiseKind, \\"getPhotos\\", @selector(getPhotos:resolve:reject:), args, count); + } + + static facebook::jsi::Value __hostFunction_NativeCameraRollManagerSpecJSI_saveToCameraRoll(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule) + .invokeObjCMethod(rt, PromiseKind, \\"saveToCameraRoll\\", @selector(saveToCameraRoll:type:resolve:reject:), args, count); + } + + static facebook::jsi::Value __hostFunction_NativeCameraRollManagerSpecJSI_deletePhotos(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule) + .invokeObjCMethod(rt, PromiseKind, \\"deletePhotos\\", @selector(deletePhotos:resolve:reject:), args, count); + } + + NativeCameraRollManagerSpecJSI::NativeCameraRollManagerSpecJSI(const ObjCTurboModule::InitParams ¶ms) + : ObjCTurboModule(params) { + + methodMap_[\\"getPhotos\\"] = MethodMetadata {1, __hostFunction_NativeCameraRollManagerSpecJSI_getPhotos}; + methodMap_[\\"saveToCameraRoll\\"] = MethodMetadata {2, __hostFunction_NativeCameraRollManagerSpecJSI_saveToCameraRoll}; + methodMap_[\\"deletePhotos\\"] = MethodMetadata {1, __hostFunction_NativeCameraRollManagerSpecJSI_deletePhotos}; + setMethodArgConversionSelector(@\\"getPhotos\\", 0, @\\"JS_NativeCameraRollManager_GetPhotosParams:\\"); + } + + static facebook::jsi::Value __hostFunction_NativeImagePickerIOSSpecJSI_openCameraDialog(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule) + .invokeObjCMethod(rt, VoidKind, \\"openCameraDialog\\", @selector(openCameraDialog:successCallback:cancelCallback:), args, count); + } + + NativeImagePickerIOSSpecJSI::NativeImagePickerIOSSpecJSI(const ObjCTurboModule::InitParams ¶ms) + : ObjCTurboModule(params) { + methodMap_[\\"openCameraDialog\\"] = MethodMetadata {3, __hostFunction_NativeImagePickerIOSSpecJSI_openCameraDialog}; + setMethodArgConversionSelector(@\\"openCameraDialog\\", 0, @\\"JS_NativeImagePickerIOS_SpecOpenCameraDialogConfig:\\"); + } + + static facebook::jsi::Value __hostFunction_NativeExceptionsManagerSpecJSI_reportFatalException(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule) + .invokeObjCMethod(rt, VoidKind, \\"reportFatalException\\", @selector(reportFatalException:stack:exceptionId:), args, count); + } + + static facebook::jsi::Value __hostFunction_NativeExceptionsManagerSpecJSI_reportSoftException(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule) + .invokeObjCMethod(rt, VoidKind, \\"reportSoftException\\", @selector(reportSoftException:stack:exceptionId:), args, count); + } + + static facebook::jsi::Value __hostFunction_NativeExceptionsManagerSpecJSI_reportException(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule) + .invokeObjCMethod(rt, VoidKind, \\"reportException\\", @selector(reportException:), args, count); + } + + static facebook::jsi::Value __hostFunction_NativeExceptionsManagerSpecJSI_updateExceptionMessage(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule) + .invokeObjCMethod(rt, VoidKind, \\"updateExceptionMessage\\", @selector(updateExceptionMessage:stack:exceptionId:), args, count); + } + + static facebook::jsi::Value __hostFunction_NativeExceptionsManagerSpecJSI_dismissRedbox(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule) + .invokeObjCMethod(rt, VoidKind, \\"dismissRedbox\\", @selector(dismissRedbox), args, count); + } + + NativeExceptionsManagerSpecJSI::NativeExceptionsManagerSpecJSI(const ObjCTurboModule::InitParams ¶ms) + : ObjCTurboModule(params) { + methodMap_[\\"reportFatalException\\"] = MethodMetadata {3, __hostFunction_NativeExceptionsManagerSpecJSI_reportFatalException}; + methodMap_[\\"reportSoftException\\"] = MethodMetadata {3, __hostFunction_NativeExceptionsManagerSpecJSI_reportSoftException}; + methodMap_[\\"reportException\\"] = MethodMetadata {1, __hostFunction_NativeExceptionsManagerSpecJSI_reportException}; + methodMap_[\\"updateExceptionMessage\\"] = MethodMetadata {3, __hostFunction_NativeExceptionsManagerSpecJSI_updateExceptionMessage}; + methodMap_[\\"dismissRedbox\\"] = MethodMetadata {0, __hostFunction_NativeExceptionsManagerSpecJSI_dismissRedbox}; + setMethodArgConversionSelector(@\\"reportException\\", 0, @\\"JS_NativeExceptionsManager_ExceptionData:\\"); + } + } // namespace react +} // namespace facebook +", +} +`; + exports[`GenerateModuleHObjCpp can generate fixture SIMPLE_NATIVE_MODULES 1`] = ` Map { "SampleSpec-generated.mm" => "