Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ public func globalCallMeIntSupplier(run: () -> Int32) -> Int32 {
run()
}

public func globalCallMeLongSupplier(run: () -> Int64) -> Int64 {
run()
}

public func globalCallMeDoubleSupplier(run: () -> Double) -> Double {
run()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ void call_globalCallMeIntSupplier_noThrow() {
assertEquals(1, result);
}

@Test
void call_globalCallMeLongSupplier_noThrow() {
long result = MySwiftLibrary.globalCallMeLongSupplier(() -> { return 1L; });
assertEquals(1L, result);
}

@Test
void call_globalCallMeDoubleSupplier_noThrow() {
double result = MySwiftLibrary.globalCallMeBooleanSupplier(() -> { return 2.0; });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ public func globalCallMeIntSupplier(run: () -> Int32) -> Int32 {
run()
}

public func globalCallMeLongSupplier(run: () -> Int64) -> Int64 {
run()
}

public func globalCallMeDoubleSupplier(run: () -> Double) -> Double {
run()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,12 @@ void call_globalCallMeIntSupplier_noThrow() {
assertEquals(2, result);
}

@Test
void call_globalCallMeLongSupplier_noThrow() {
long result = MySwiftLibrary.globalCallMeLongSupplier(() -> { return 2L; });
assertEquals(2L, result);
}

@Test
void call_globalCallMeDoubleSupplier_noThrow() {
double result = MySwiftLibrary.globalCallMeDoubleSupplier(() -> { return 2.0; });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ public func globalCallMeIntSupplier(run: () -> Int32) -> Int32 {
run()
}

public func globalCallMeLongSupplier(run: () -> Int64) -> Int64 {
run()
}

public func globalCallMeDoubleSupplier(run: () -> Double) -> Double {
run()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ void globalCallMeIntSupplier() {
assertEquals(2, result);
}

@Test
void globalCallMeLongSupplier() {
long result = MySwiftLibrary.globalCallMeLongSupplier(() -> 2L);
assertEquals(2L, result);
}

@Test
void globalCallMeDoubleSupplier() {
double result = MySwiftLibrary.globalCallMeDoubleSupplier(() -> 2.0);
Expand Down
4 changes: 4 additions & 0 deletions Sources/ExampleSwiftLibrary/MySwiftLibrary.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ public func globalCallMeIntSupplier(run: () -> Int32) -> Int32 {
run()
}

public func globalCallMeLongSupplier(run: () -> Int64) -> Int64 {
run()
}

public func globalCallMeDoubleSupplier(run: () -> Double) -> Double {
run()
}
Expand Down
5 changes: 5 additions & 0 deletions Sources/JExtractSwiftLib/JavaTypes/JavaType+JDK.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ extension JavaType {
.class(package: "java.util.function", name: "IntSupplier")
}

/// The description of the type java.util.function.LongSupplier.
static var javaUtilFunctionLongSupplier: JavaType {
.class(package: "java.util.function", name: "LongSupplier")
}

/// The description of the type java.util.function.DoubleSupplier.
static var javaUtilFunctionDoubleSupplier: JavaType {
.class(package: "java.util.function", name: "DoubleSupplier")
Expand Down
10 changes: 10 additions & 0 deletions Sources/JExtractSwiftLib/KnownFunctionalInterfaces.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ struct KnownJavaFunctionalInterface: Sendable {
result: .int
)

static let longSupplier = KnownJavaFunctionalInterface(
JavaType.javaUtilFunctionLongSupplier,
method: "getAsLong",
parameters: [],
result: .long
)

static let doubleSupplier = KnownJavaFunctionalInterface(
JavaType.javaUtilFunctionDoubleSupplier,
method: "getAsDouble",
Expand All @@ -54,6 +61,7 @@ struct KnownJavaFunctionalInterface: Sendable {
.runnable,
.booleanSupplier,
.intSupplier,
.longSupplier,
.doubleSupplier,
]

Expand Down Expand Up @@ -87,6 +95,8 @@ struct KnownJavaFunctionalInterface: Sendable {
booleanSupplier
case ([], _) where result.isInt32:
intSupplier
case ([], _) where result.isInt64:
longSupplier
case ([], _) where result.isDouble:
doubleSupplier
default:
Expand Down
11 changes: 11 additions & 0 deletions Sources/SwiftExtract/SwiftTypes/SwiftType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,17 @@ public enum SwiftType: Equatable {
}
}

public var isInt64: Bool {
switch self {
case .nominal(let nominal):
switch nominal.nominalTypeDecl.knownTypeKind {
case .int64, .uint64: true
default: false
}
default: false
}
}

public var isUnsignedInteger: Bool {
switch self {
case .nominal(let nominal):
Expand Down
44 changes: 44 additions & 0 deletions Tests/JExtractSwiftTests/FuncCallbackImportTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ final class FuncCallbackImportTests {
public func callMe(callback: () -> Void)
public func callMeBoolSupplier(callback: () -> Bool)
public func callMeIntSupplier(callback: () -> Int32)
public func callMeLongSupplier(callback: () -> Int64)
public func callMeDoubleSupplier(callback: () -> Double)
public func callMeMore(callback: (UnsafeRawPointer, Float) -> Int, fn: () -> ())
public func withBuffer(body: (UnsafeRawBufferPointer) -> Int)
Expand Down Expand Up @@ -254,6 +255,49 @@ final class FuncCallbackImportTests {
)
}

@Test("Import: public func callMeLongSupplier(callback: () -> Int64)")
func func_callMeLongSupplierFunc_callback() throws {
var config = Configuration()
config.swiftModule = "__FakeModule"
let st = makeSwiftJavaAnalyzer(config: config)
st.log.logLevel = .error

try st.analyze(path: "Fake.swift", text: Self.class_interfaceFile)

let funcDecl = st.extractedGlobalFuncs.first { $0.name == "callMeLongSupplier" }!

let generator = FFMSwift2JavaGenerator(
config: config,
translator: st,
javaPackage: "com.example.swift",
swiftOutputDirectory: "/fake",
javaOutputDirectory: "/fake"
)

let output = JavaPrinter.toString { printer in
generator.printFunctionDowncallMethods(&printer, funcDecl)
}

assertOutput(
output,
expectedChunks: [
"""
/**
* Downcall to Swift:
* {@snippet lang=swift :
* public func callMeLongSupplier(callback: () -> Int64)
* }
*/
public static void callMeLongSupplier(java.util.function.LongSupplier callback) {
try(var arena$ = Arena.ofConfined()) {
swiftjava___FakeModule_callMeLongSupplier_callback.call(callMeLongSupplier.$toUpcallStub(callback, arena$));
}
}
"""
]
)
}

@Test("Import: public func callMeDoubleSupplier(callback: () -> Double)")
func func_callMeDoubleSupplierFunc_callback() throws {
var config = Configuration()
Expand Down
51 changes: 51 additions & 0 deletions Tests/JExtractSwiftTests/JNI/JNIClosureTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ struct JNIClosureTests {
public func emptyClosure(closure: () -> ()) {}
public func closureBoolSupplier(closure: () -> Bool) {}
public func closureIntSupplier(closure: () -> Int32) {}
public func closureLongSupplier(closure: () -> Int64) {}
public func closureDoubleSupplier(closure: () -> Double) {}
public func closureWithArgumentsAndReturn(closure: (Int64, Bool) -> Int64) {}
"""
Expand Down Expand Up @@ -101,6 +102,31 @@ struct JNIClosureTests {
)
}

@Test
func closureLongSupplier_javaBindings() throws {
try assertOutput(
input: source,
.jni,
.java,
expectedChunks: [
"""
/**
* Downcall to Swift:
* {@snippet lang=swift :
* public func closureLongSupplier(closure: () -> Int64)
* }
*/
public static void closureLongSupplier(java.util.function.LongSupplier closure) {
SwiftModule.$closureLongSupplier(closure);
}
""",
"""
private static native void $closureLongSupplier(java.util.function.LongSupplier closure);
""",
]
)
}

@Test
func closureDoubleSupplier_javaBindings() throws {
try assertOutput(
Expand Down Expand Up @@ -201,6 +227,31 @@ struct JNIClosureTests {
)
}

@Test
func closureLongSupplier_swiftThunks() throws {
try assertOutput(
input: source,
.jni,
.swift,
detectChunkByInitialLines: 1,
expectedChunks: [
"""
@_cdecl("Java_com_example_swift_SwiftModule__00024closureLongSupplier__Ljava_util_function_LongSupplier_2")
public func Java_com_example_swift_SwiftModule__00024closureLongSupplier__Ljava_util_function_LongSupplier_2(environment: UnsafeMutablePointer<JNIEnv?>!, thisClass: jclass, closure: jobject?) {
SwiftModule.closureLongSupplier(closure: {
let class$ = environment.interface.GetObjectClass(environment, closure)
let methodID$ = environment.interface.GetMethodID(environment, class$, "getAsLong", "()J")!
environment.interface.DeleteLocalRef(environment, class$)
let arguments$: [jvalue] = []
return Int64(fromJNI: environment.interface.CallLongMethodA(environment, closure, methodID$, arguments$), in: environment)
}
)
}
"""
]
)
}

@Test
func closureDoubleSupplier_swiftThunks() throws {
try assertOutput(
Expand Down
Loading