UNPKG

nitro-codegen

Version:

The code-generator for react-native-nitro-modules.

79 lines (71 loc) 2.64 kB
import { indent } from '../../utils.js'; import { createFileMetadataString } from '../helpers.js'; import { SwiftCxxBridgedType } from './SwiftCxxBridgedType.js'; import { getBridgeNamespace } from './SwiftHybridObjectBridge.js'; export function createSwiftFunctionBridge(functionType) { const swiftClassName = functionType.specializationName; const argsTypes = functionType.parameters.map((p) => { const bridged = new SwiftCxxBridgedType(p); return `${p.escapedName}: ${bridged.getTypeCode('swift')}`; }); const returnType = new SwiftCxxBridgedType(functionType.returnType); const argsForward = functionType.parameters.map((p) => { const bridged = new SwiftCxxBridgedType(p); return bridged.parseFromCppToSwift(p.escapedName, 'swift'); }); let body; if (functionType.returnType.kind === 'void') { body = ` self.closure(${argsForward.join(', ')}) `.trim(); } else { body = ` let __result: ${functionType.returnType.getCode('swift')} = self.closure(${argsForward.join(', ')}) return ${returnType.parseFromSwiftToCpp('__result', 'swift')} `.trim(); } const code = ` ${createFileMetadataString(`${swiftClassName}.swift`)} import NitroModules /** * Wraps a Swift \`${functionType.getCode('swift')}\` as a class. * This class can be used from C++, e.g. to wrap the Swift closure as a \`std::function\`. */ public final class ${swiftClassName} { public typealias bridge = ${getBridgeNamespace()} private let closure: ${functionType.getCode('swift')} public init(_ closure: @escaping ${functionType.getCode('swift')}) { self.closure = closure } @inline(__always) public func call(${argsTypes.join(', ')}) -> ${returnType.getTypeCode('swift')} { ${indent(body, ' ')} } /** * Casts this instance to a retained unsafe raw pointer. * This acquires one additional strong reference on the object! */ @inline(__always) public func toUnsafe() -> UnsafeMutableRawPointer { return Unmanaged.passRetained(self).toOpaque() } /** * Casts an unsafe pointer to a \`${swiftClassName}\`. * The pointer has to be a retained opaque \`Unmanaged<${swiftClassName}>\`. * This removes one strong reference from the object! */ @inline(__always) public static func fromUnsafe(_ pointer: UnsafeMutableRawPointer) -> ${swiftClassName} { return Unmanaged<${swiftClassName}>.fromOpaque(pointer).takeRetainedValue() } } `.trim(); return { content: code, language: 'swift', name: `${swiftClassName}.swift`, platform: 'ios', subdirectory: [], }; }