diff --git a/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+NativeTranslation.swift b/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+NativeTranslation.swift index a262e5fc9..229e48f55 100644 --- a/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+NativeTranslation.swift +++ b/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+NativeTranslation.swift @@ -2000,7 +2000,10 @@ extension JNISwift2JavaGenerator { printer.print("environment = try! JavaVirtualMachine.shared().environment()") let inner = nativeFunctionSignature.result.conversion.render(&printer, "swiftResult$") let result: String - if nativeFunctionSignature.result.javaType.requiresBoxing { + if nativeFunctionSignature.result.javaType.isVoid { + // The result was written to the out parameters, so the Java future is completed with Void + result = "nil" + } else if nativeFunctionSignature.result.javaType.requiresBoxing { printer.print( "let boxedResult$ = SwiftJavaRuntimeSupport._JNIBoxedConversions.box(\(inner), in: environment)" ) diff --git a/Tests/JExtractSwiftTests/JNI/JNIAsyncTests.swift b/Tests/JExtractSwiftTests/JNI/JNIAsyncTests.swift index 7c968e419..825204af7 100644 --- a/Tests/JExtractSwiftTests/JNI/JNIAsyncTests.swift +++ b/Tests/JExtractSwiftTests/JNI/JNIAsyncTests.swift @@ -482,4 +482,51 @@ struct JNIAsyncTests { ] ) } + + @Test( + "Import: async with result in out parameters completes future with nil (Swift, CompletableFuture)", + arguments: [ + ( + """ + public struct MyID { + public var rawValue: T + } + public func asyncGeneric() async -> MyID + """, + "asyncGeneric" + ), + ( + """ + public protocol Shape { + func area() -> Double + } + public func asyncExistential() async -> any Shape + """, + "asyncExistential" + ), + ( + "public func asyncTuple() async -> (Int64, String)", + "asyncTuple" + ), + ] + ) + func completableFuture_asyncOutParameterResult_swift(input: String, functionName: String) throws { + try assertOutput( + input: input, + .jni, + .swift, + detectChunkByInitialLines: 1, + expectedChunks: [ + """ + let swiftResult$ = await SwiftModule.\(functionName)() + environment = try! JavaVirtualMachine.shared().environment() + ... + _ = environment.interface.CallBooleanMethodA(environment, globalFuture, _JNIMethodIDCache.CompletableFuture.complete, [jvalue(l: nil)]) + """ + ], + notExpectedChunks: [ + "[jvalue(l: )]" + ] + ) + } }