Skip to content
Open
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 @@ -100,6 +100,14 @@ public func globalCallMeDoubleBinaryOperator(run: (Double, Double) -> Double) ->
run(1.0, 2.0)
}

public func globalCallMeDoubleToIntFunction(run: (Double) -> Int32) -> Int32 {
run(1.0)
}

public func globalCallMeLongToIntFunction(run: (Int64) -> Int32) -> Int32 {
run(1)
}

// ==== Internal helpers

func p(_ msg: String, file: String = #fileID, line: UInt = #line, function: String = #function) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,4 +146,16 @@ void call_globalCallMeDoubleBinaryOperator_noThrow() {
double result = MySwiftLibrary.globalCallMeDoubleBinaryOperator((double a, double b) -> { return a + b; });
assertEquals(3.0, result);
}

@Test
void call_globalCallMeDoubleToIntFunction_noThrow() {
int result = MySwiftLibrary.globalCallMeDoubleToIntFunction((double a) -> { return (int) a; });
assertEquals(1, result);
}

@Test
void call_globalCallMeLongToIntFunction_noThrow() {
int result = MySwiftLibrary.globalCallMeLongToIntFunction((long a) -> { return (int) a; });
assertEquals(1, result);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,14 @@ public func globalCallMeDoubleBinaryOperator(run: (Double, Double) -> Double) ->
run(1.0, 2.0)
}

public func globalCallMeDoubleToIntFunction(run: (Double) -> Int32) -> Int32 {
run(1.0)
}

public func globalCallMeLongToIntFunction(run: (Int64) -> Int32) -> Int32 {
run(1)
}

public func globalReceiveRawBuffer(buf: UnsafeRawBufferPointer) -> Int {
buf.count
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -258,4 +258,16 @@ void call_globalCallMeDoubleBinaryOperator_noThrow() {
double result = MySwiftLibrary.globalCallMeDoubleBinaryOperator((double a, double b) -> { return a + b; });
assertEquals(3.0, result);
}

@Test
void call_globalCallMeDoubleToIntFunction_noThrow() {
int result = MySwiftLibrary.globalCallMeDoubleToIntFunction((double a) -> { return (int) a; });
assertEquals(1, result);
}

@Test
void call_globalCallMeLongToIntFunction_noThrow() {
int result = MySwiftLibrary.globalCallMeLongToIntFunction((long a) -> { return (int) a; });
assertEquals(1, result);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,14 @@ public func globalCallMeDoubleBinaryOperator(run: (Double, Double) -> Double) ->
run(1.0, 2.0)
}

public func globalCallMeDoubleToIntFunction(run: (Double) -> Int32) -> Int32 {
run(1.0)
}

public func globalCallMeLongToIntFunction(run: (Int64) -> Int32) -> Int32 {
run(1)
}

public func closureMultipleArguments(
input1: Int64,
input2: Int64,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,4 +140,16 @@ void globalCallMeDoubleBinaryOperator() {
double result = MySwiftLibrary.globalCallMeDoubleBinaryOperator((double a, double b) -> { return a + b; });
assertEquals(3.0, result);
}

@Test
void globalCallMeDoubleToIntFunction() {
int result = MySwiftLibrary.globalCallMeDoubleToIntFunction((double a) -> { return (int) a; });
assertEquals(1, result);
}

@Test
void globalCallMeLongToIntFunction() {
int result = MySwiftLibrary.globalCallMeLongToIntFunction((long a) -> { return (int) a; });
assertEquals(1, result);
}
}
8 changes: 8 additions & 0 deletions Sources/ExampleSwiftLibrary/MySwiftLibrary.swift
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,14 @@ public func globalCallMeDoubleBinaryOperator(run: (Double, Double) -> Double) ->
run(1.0, 2.0)
}

public func globalCallMeDoubleToIntFunction(run: (Double) -> Int32) -> Int32 {
run(1.0)
}

public func globalCallMeLongToIntFunction(run: (Int64) -> Int32) -> Int32 {
run(1)
}

public func globalReceiveRawBuffer(buf: UnsafeRawBufferPointer) -> Int {
buf.count
}
Expand Down
10 changes: 10 additions & 0 deletions Sources/JExtractSwiftLib/JavaTypes/JavaType+JDK.swift
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,16 @@ extension JavaType {
.class(package: "java.util.function", name: "DoubleBinaryOperator")
}

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

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

/// The description of the type java.lang.Class.
static var javaLangClass: JavaType {
.class(package: "java.lang", name: "Class")
Expand Down
29 changes: 29 additions & 0 deletions Sources/JExtractSwiftLib/KnownFunctionalInterfaces.swift
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,20 @@ struct KnownJavaFunctionalInterface: Sendable {
result: .double
)

static let doubleToIntFunction = KnownJavaFunctionalInterface(
JavaType.javaUtilFunctionDoubleToIntFunction,
method: "applyAsInt",
parameters: [.double],
result: .int
)

static let longToIntFunction = KnownJavaFunctionalInterface(
JavaType.javaUtilFunctionLongToIntFunction,
method: "applyAsInt",
parameters: [.long],
result: .int
)

static let all: [KnownJavaFunctionalInterface] = [
.runnable,
.booleanSupplier,
Expand All @@ -159,6 +173,8 @@ struct KnownJavaFunctionalInterface: Sendable {
.intBinaryOperator,
.longBinaryOperator,
.doubleBinaryOperator,
.doubleToIntFunction,
.longToIntFunction,
]

static func find(parameters: [JavaType], result: JavaType) -> KnownJavaFunctionalInterface? {
Expand Down Expand Up @@ -248,6 +264,19 @@ struct KnownJavaFunctionalInterface: Sendable {
}
}

// To int functions
if parameters.count == 1 && result.isInt32 {
let parameter = parameters[0].type
return switch () {
case _ where parameter.isInt64:
longToIntFunction
case _ where parameter.isDouble:
doubleToIntFunction
default:
nil
}
}

// Binary operators
if parameters.count == 2 && parameters[0].type == result && parameters[1].type == result {
let parameter = parameters[0].type
Expand Down
89 changes: 89 additions & 0 deletions Tests/JExtractSwiftTests/FuncCallbackImportTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ final class FuncCallbackImportTests {
public func callMeLongPredicate(callback: (Int64) -> Bool)
public func callMeDoublePredicate(callback: (Double) -> Bool)

public func callMeDoubleToIntFunction(callback: (Double) -> Int32)
public func callMeLongToIntFunction(callback: (Int64) -> Int32)

public func callMeIntUnaryOperator(callback: (Int32) -> Int32)
public func callMeLongUnaryOperator(callback: (Int64) -> Int64)
public func callMeDoubleUnaryOperator(callback: (Double) -> Double)
Expand Down Expand Up @@ -854,6 +857,92 @@ final class FuncCallbackImportTests {
)
}

@Test("Import: public func callMeDoubleToIntFunction(callback: (Double) -> Int32)")
func func_callMecallMeDoubleToIntFunctionFunc_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 == "callMeDoubleToIntFunction" }!

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 callMeDoubleToIntFunction(callback: (Double) -> Int32)
* }
*/
public static void callMeDoubleToIntFunction(java.util.function.DoubleToIntFunction callback) {
try(var arena$ = Arena.ofConfined()) {
swiftjava___FakeModule_callMeDoubleToIntFunction_callback.call(callMeDoubleToIntFunction.$toUpcallStub(callback, arena$));
}
}
"""
]
)
}

@Test("Import: public func callMeLongToIntFunction(callback: (Int64) -> Int32)")
func func_callMecallMeLongToIntFunctionFunc_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 == "callMeLongToIntFunction" }!

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 callMeLongToIntFunction(callback: (Int64) -> Int32)
* }
*/
public static void callMeLongToIntFunction(java.util.function.LongToIntFunction callback) {
try(var arena$ = Arena.ofConfined()) {
swiftjava___FakeModule_callMeLongToIntFunction_callback.call(callMeLongToIntFunction.$toUpcallStub(callback, arena$));
}
}
"""
]
)
}

@Test("Import: public func callMecallMeIntBinaryOperatorFunc(callback: (Int32, Int32) -> Int32)")
func func_callMecallMeIntBinaryOperatorFunc_callback() throws {
var config = Configuration()
Expand Down
Loading
Loading