Skip to content

Commit 4529f3e

Browse files
committed
support objects as associated values
1 parent cd65619 commit 4529f3e

File tree

3 files changed

+27
-17
lines changed

3 files changed

+27
-17
lines changed

Samples/JExtractJNISampleApp/src/test/java/com/example/swift/VehicleEnumTest.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,16 @@ void getAsMotorbike() {
114114
}
115115
}
116116

117+
@Test
118+
void getAsTransformer() {
119+
try (var arena = new ConfinedSwiftMemorySession()) {
120+
Vehicle vehicle = Vehicle.transformer(Vehicle.bicycle(arena), Vehicle.car("BMW", arena), arena);
121+
Vehicle.Transformer transformer = vehicle.getAsTransformer(arena).orElseThrow();
122+
assertTrue(transformer.front().getAsBicycle().isPresent());
123+
assertEquals("BMW", transformer.back().getAsCar().orElseThrow().arg0());
124+
}
125+
}
126+
117127
@Test
118128
void associatedValuesAreCopied() {
119129
try (var arena = new ConfinedSwiftMemorySession()) {

Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaBindingsPrinting.swift

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -265,16 +265,17 @@ extension JNISwift2JavaGenerator {
265265
var nativeResults = zip(translatedCase.translatedValues, translatedCase.conversions).map { value, conversion in
266266
"\(conversion.native.javaType) \(value.parameter.name)"
267267
}
268-
if requiresSwiftArena {
269-
nativeResults.append("SwiftArena swiftArena$")
270-
}
268+
printer.print("record $NativeParameters(\(nativeResults.joined(separator: ", "))) {}")
269+
printer.println()
270+
271271
printer.print(#"@SuppressWarnings("unused")"#)
272-
printer.printBraceBlock("static \(caseName) fromJNI(\(nativeResults.joined(separator: ", ")))") { printer in
272+
let swiftArenaParameter = requiresSwiftArena ? ", SwiftArena swiftArena$" : ""
273+
printer.printBraceBlock("\(caseName)($NativeParameters parameters\(swiftArenaParameter))") { printer in
273274
let memberValues = zip(translatedCase.translatedValues, translatedCase.conversions).map { (value, conversion) in
274-
let result = conversion.translated.conversion.render(&printer, value.parameter.name)
275+
let result = conversion.translated.conversion.render(&printer, "parameters.\(value.parameter.name)")
275276
return result
276277
}
277-
printer.print("return new \(caseName)(\(memberValues.joined(separator: ", ")));")
278+
printer.print("this(\(memberValues.joined(separator: ", ")));")
278279
}
279280
}
280281
}
@@ -291,24 +292,22 @@ extension JNISwift2JavaGenerator {
291292
"""
292293
)
293294
if hasParameters {
294-
var arguments = ["this.$memoryAddress()"]
295+
var arguments = ["$getAs\(caseName)(this.$memoryAddress())"]
295296
if requiresSwiftArena {
296297
arguments.append("swiftArena$")
297298
}
298299
printer.print(
299300
"""
300-
return Optional.of($getAs\(caseName)(\(arguments.joined(separator: ", "))));
301+
return Optional.of(new \(caseName)(\(arguments.joined(separator: ", "))));
301302
"""
302303
)
303304
} else {
304305
printer.print("return Optional.of(new \(caseName)());")
305306
}
306307
}
307-
var nativeParameters = ["long self"]
308-
if requiresSwiftArena {
309-
nativeParameters.append("SwiftArena swiftArena$")
308+
if hasParameters {
309+
printer.print("private static native \(caseName).$NativeParameters $getAs\(caseName)(long self);")
310310
}
311-
printer.print("private static native \(caseName) $getAs\(caseName)(\(nativeParameters.joined(separator: ", ")));")
312311

313312
printer.println()
314313
}

Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+SwiftThunkPrinting.swift

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,8 @@ extension JNISwift2JavaGenerator {
159159
// Print getAsCase method
160160
if !enumCase.parameters.isEmpty {
161161
let selfParameter = JavaParameter(name: "self", type: .long)
162-
let resultType = JavaType.class(package: javaPackage, name: "\(translatedCase.enumName).\(translatedCase.name)")
162+
163+
let resultType = JavaType.class(package: javaPackage, name: "\(translatedCase.enumName).\(translatedCase.name).$NativeParameters")
163164
printCDecl(
164165
&printer,
165166
javaMethodName: "$getAs\(translatedCase.name)",
@@ -176,15 +177,15 @@ extension JNISwift2JavaGenerator {
176177
parameter.name ?? "_\(idx)"
177178
}
178179
let caseNamesWithLet = caseNames.map { "let \($0)" }
179-
let methodSignature = MethodSignature(resultType: resultType, parameterTypes: translatedCase.conversions.map(\.native.javaType))
180+
let methodSignature = MethodSignature(resultType: .void, parameterTypes: translatedCase.conversions.map(\.native.javaType))
180181
// TODO: Caching of class and static method ID.
181182
printer.print(
182183
"""
183184
guard case .\(enumCase.name)(\(caseNamesWithLet.joined(separator: ", "))) = \(selfPointer).pointee else {
184185
fatalError("Expected enum case '\(enumCase.name)', but was '\\(self$.pointee)'!")
185186
}
186-
let recordClass$ = environment.interface.FindClass(environment, "\(javaPackagePath)/\(translatedCase.enumName)$\(translatedCase.name)")!
187-
let fromJNIID$ = environment.interface.GetStaticMethodID(environment, recordClass$, "fromJNI", "\(methodSignature.mangledName)")!
187+
let class$ = environment.interface.FindClass(environment, "\(javaPackagePath)/\(translatedCase.enumName)$\(translatedCase.name)$$NativeParameters")!
188+
let constructorID$ = environment.interface.GetMethodID(environment, class$, "<init>", "\(methodSignature.mangledName)")!
188189
"""
189190
)
190191

@@ -197,7 +198,7 @@ extension JNISwift2JavaGenerator {
197198
printer.print(
198199
"""
199200
return withVaList([\(upcallArguments.joined(separator: ", "))]) {
200-
return environment.interface.CallStaticObjectMethodV(environment, recordClass$, fromJNIID$, $0)
201+
return environment.interface.NewObjectV(environment, class$, constructorID$, $0)
201202
}
202203
"""
203204
)

0 commit comments

Comments
 (0)