Skip to content

Commit 2c28a44

Browse files
piercifaniclaude
andcommitted
JNI: closures taking optional strings and numbers wrap them as Java optionals
A closure taking `String?` converts the argument with `toJavaOptional()`, which makes a `JavaOptional<JavaString>`, but the closure's `@JavaInterface` declared the parameter as `String?`, so the generated Swift didn't compile. Optional `String`, `Double`, `Int32` and `Int64` parameters now use the types `toJavaOptional()` returns. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent f6497b0 commit 2c28a44

2 files changed

Lines changed: 22 additions & 0 deletions

File tree

‎Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+EscapingClosureWrapJava.swift‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,16 @@ extension JNISwift2JavaGenerator {
9393
if !isResult, let nominal = optionalWrapped(type).flatMap(jextractedNominal) {
9494
return "JavaOptional<\(nominal.generatedJavaClassMacroName)>?"
9595
}
96+
// Optional strings and numbers cross as what `Optional.toJavaOptional()` makes of them.
97+
if !isResult, let wrapped = optionalWrapped(type), case .nominal(let nominal) = wrapped {
98+
switch nominal.nominalTypeDecl.knownTypeKind {
99+
case .string: return "JavaOptional<JavaString>?"
100+
case .double: return "JavaOptionalDouble?"
101+
case .int32: return "JavaOptionalInt?"
102+
case .int64: return "JavaOptionalLong?"
103+
default: break
104+
}
105+
}
96106
// Arrays of jextracted values cross as arrays of their Java objects.
97107
if !isResult, case .nominal(let array) = type, case .array(let element) = array.asKnownType,
98108
let nominal = jextractedNominal(element)

‎Tests/JExtractSwiftTests/JNI/JNIEscapingClosureJExtractedTypesTests.swift‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,4 +228,16 @@ struct JNIEscapingClosureJExtractedTypesTests {
228228
]
229229
)
230230
}
231+
232+
@Test
233+
func closureTakingOptionalString_usesJavaOptional() throws {
234+
try assertOutput(
235+
input: "public func onVerify(_ cb: @escaping (String?, Int64?) -> Void) {}",
236+
.jni,
237+
.swift,
238+
expectedChunks: [
239+
"public func apply(_ _0: JavaOptional<JavaString>?, _ _1: JavaOptionalLong?)"
240+
]
241+
)
242+
}
231243
}

0 commit comments

Comments
 (0)