nitro-codegen
Version:
The code-generator for react-native-nitro-modules.
79 lines (71 loc) • 2.64 kB
JavaScript
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: [],
};
}