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 @@ -99,6 +99,10 @@ public class MySwiftClass {
public func addXWithJavaLong(_ other: JavaLong) -> Int64 {
self.x + other.longValue()
}

public func returnXAsJavaLong() -> JavaLong {
JavaLong(self.x)
}
}

extension MySwiftClass: CustomStringConvertible {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,15 @@ void addXWithJavaLong() {
}
}

@Test
void returnXAsJavaLong() {
try (var arena = SwiftArena.ofConfined()) {
MySwiftClass c1 = MySwiftClass.init(20, 10, arena);
Long javaLong = c1.returnXAsJavaLong();
assertEquals(20L, javaLong);
}
}

@Test
void getAsyncVariable() throws Exception {
try (var arena = SwiftArena.ofConfined()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -899,6 +899,7 @@ extension JNISwift2JavaGenerator {

switch swiftType {
case .nominal(let nominalType):
let nominalTypeName = nominalType.nominalTypeDecl.qualifiedName
if let knownType = nominalType.asKnownType {
switch knownType {
case .optional(let wrapped):
Expand Down Expand Up @@ -964,7 +965,16 @@ extension JNISwift2JavaGenerator {
}

if nominalType.isSwiftJavaWrapper {
throw JavaTranslationError.unsupportedSwiftType(swiftType)
guard let javaType = nominalTypeName.parseJavaClassFromSwiftJavaName(in: self.javaClassLookupTable) else {
throw JavaTranslationError.wrappedJavaClassTranslationNotProvided(swiftType)
}
return TranslatedResult(
javaType: javaType,
nativeJavaType: javaType,
annotations: resultAnnotations,
outParameters: [],
conversion: .placeholder
)
}

let javaType = JavaType.class(
Expand Down Expand Up @@ -1292,6 +1302,7 @@ extension JNISwift2JavaGenerator {

switch swiftType {
case .nominal(let nominalType):
let nominalTypeName = nominalType.nominalTypeDecl.qualifiedName
if let knownType = nominalType.nominalTypeDecl.knownTypeKind {
if let javaType = JNIJavaTypeTranslator.translate(knownType: knownType, config: self.config),
javaType.implementsJavaValue
Expand Down Expand Up @@ -1339,8 +1350,17 @@ extension JNISwift2JavaGenerator {
}
}

guard !nominalType.isSwiftJavaWrapper else {
throw JavaTranslationError.unsupportedSwiftType(swiftType)
if nominalType.isSwiftJavaWrapper {
guard let javaType = nominalTypeName.parseJavaClassFromSwiftJavaName(in: self.javaClassLookupTable) else {
throw JavaTranslationError.wrappedJavaClassTranslationNotProvided(swiftType)
}
return TranslatedResult(
javaType: javaType,
nativeJavaType: javaType,
annotations: parameterAnnotations,
outParameters: [],
conversion: .placeholder
)
}

case .tuple:
Expand Down Expand Up @@ -1488,6 +1508,7 @@ extension JNISwift2JavaGenerator {
)

case .nominal(let nominalType):
let nominalTypeName = nominalType.nominalTypeDecl.qualifiedName
if let knownType = nominalType.nominalTypeDecl.knownTypeKind {
guard let javaType = JNIJavaTypeTranslator.translate(knownType: knownType, config: self.config) else {
throw JavaTranslationError.unsupportedSwiftType(elementType)
Expand All @@ -1502,8 +1523,18 @@ extension JNISwift2JavaGenerator {
)
}

guard !nominalType.isSwiftJavaWrapper else {
throw JavaTranslationError.unsupportedSwiftType(elementType)
if nominalType.isSwiftJavaWrapper {
guard let javaType = nominalTypeName.parseJavaClassFromSwiftJavaName(in: self.javaClassLookupTable) else {
throw JavaTranslationError.wrappedJavaClassTranslationNotProvided(elementType)
}

return TranslatedResult(
javaType: .array(javaType),
nativeJavaType: .array(javaType),
annotations: annotations,
outParameters: [],
conversion: .placeholder
)
}

let javaType = try translateGenericTypeParameter(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -649,6 +649,7 @@ extension JNISwift2JavaGenerator {

switch swiftType {
case .nominal(let nominalType):
let nominalTypeName = nominalType.nominalTypeDecl.qualifiedName
if let knownType = nominalType.nominalTypeDecl.knownTypeKind {
if let javaType = JNIJavaTypeTranslator.translate(knownType: knownType, config: self.config),
javaType.implementsJavaValue
Expand Down Expand Up @@ -697,9 +698,16 @@ extension JNISwift2JavaGenerator {
}
}

guard !nominalType.isSwiftJavaWrapper else {
// TODO: Should be the same as above
throw JavaTranslationError.unsupportedSwiftType(swiftType)
if nominalType.isSwiftJavaWrapper {
guard let javaType = nominalTypeName.parseJavaClassFromSwiftJavaName(in: self.javaClassLookupTable) else {
throw JavaTranslationError.wrappedJavaClassTranslationNotProvided(swiftType)
}

return NativeResult(
javaType: javaType,
conversion: .getJNIValue(.placeholder),
outParameters: []
)
}

case .tuple:
Expand Down Expand Up @@ -812,6 +820,7 @@ extension JNISwift2JavaGenerator {
) throws -> NativeResult {
switch swiftType {
case .nominal(let nominalType):
let nominalTypeName = nominalType.nominalTypeDecl.qualifiedName
if let knownType = nominalType.asKnownType {
switch knownType {
case .optional(let wrapped):
Expand Down Expand Up @@ -871,7 +880,14 @@ extension JNISwift2JavaGenerator {
}

if nominalType.isSwiftJavaWrapper {
throw JavaTranslationError.unsupportedSwiftType(swiftType)
guard let javaType = nominalTypeName.parseJavaClassFromSwiftJavaName(in: self.javaClassLookupTable) else {
throw JavaTranslationError.wrappedJavaClassTranslationNotProvided(swiftType)
}
return NativeResult(
javaType: javaType,
conversion: .getJNIValue(.placeholder),
outParameters: []
)
}

if nominalType.nominalTypeDecl.isGeneric {
Expand Down Expand Up @@ -1001,6 +1017,7 @@ extension JNISwift2JavaGenerator {
)

case .nominal(let nominalType):
let nominalTypeName = nominalType.nominalTypeDecl.qualifiedName
if let knownType = nominalType.nominalTypeDecl.knownTypeKind {
guard let javaType = JNIJavaTypeTranslator.translate(knownType: knownType, config: self.config),
javaType.implementsJavaValue
Expand All @@ -1015,8 +1032,16 @@ extension JNISwift2JavaGenerator {
)
}

guard !nominalType.isSwiftJavaWrapper else {
throw JavaTranslationError.unsupportedSwiftType(known: .array(elementType))
if nominalType.isSwiftJavaWrapper {
guard let javaType = nominalTypeName.parseJavaClassFromSwiftJavaName(in: self.javaClassLookupTable) else {
throw JavaTranslationError.wrappedJavaClassTranslationNotProvided(elementType)
}

return NativeResult(
javaType: .array(javaType),
conversion: .getJNIValue(.placeholder),
outParameters: []
)
}

// Assume JExtract imported class
Expand Down
138 changes: 136 additions & 2 deletions Tests/JExtractSwiftTests/JNI/JNIJavaKitTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ import Testing

@Suite
struct JNIJavaKitTests {
let source =
"""
let source = """
public func function(javaLong: JavaLong, javaInteger: JavaInteger, int: Int64) {}
"""

Expand Down Expand Up @@ -77,4 +76,139 @@ struct JNIJavaKitTests {
]
)
}

@Test
func functionReturn_javaBindings() throws {
try assertOutput(
input: "public func function() -> JavaLong",
.jni,
.java,
javaClassLookupTable: classLookupTable,
expectedChunks: [
"""
/**
* Downcall to Swift:
* {@snippet lang=swift :
* public func function() -> JavaLong
* }
*/
public static java.lang.Long function() {
return SwiftModule.$function();
}
""",
"""
private static native java.lang.Long $function();
""",
]
)
}

@Test
func functionReturn_swiftThunks() throws {
try assertOutput(
input: "public func function() -> JavaLong",
.jni,
.swift,
detectChunkByInitialLines: 1,
javaClassLookupTable: classLookupTable,
expectedChunks: [
"""
@_cdecl("Java_com_example_swift_SwiftModule__00024function__")
public func Java_com_example_swift_SwiftModule__00024function__(environment: UnsafeMutablePointer<JNIEnv?>!, thisClass: jclass) -> jobject? {
return SwiftModule.function().getJNILocalRefValue(in: environment)
}
"""
]
)
}

@Test
func functionReturnOptional_javaBindings() throws {
try assertOutput(
input: "public func function() -> JavaLong?",
.jni,
.java,
javaClassLookupTable: classLookupTable,
expectedChunks: [
"""
/**
* Downcall to Swift:
* {@snippet lang=swift :
* public func function() -> JavaLong?
* }
*/
public static java.lang.Long function() {
return SwiftModule.$function();
}
""",
"""
private static native java.lang.Long $function();
""",
]
)
}

@Test
func functionReturnOptional_swiftThunks() throws {
try assertOutput(
input: "public func function() -> JavaLong?",
.jni,
.swift,
detectChunkByInitialLines: 1,
javaClassLookupTable: classLookupTable,
expectedChunks: [
"""
@_cdecl("Java_com_example_swift_SwiftModule__00024function__")
public func Java_com_example_swift_SwiftModule__00024function__(environment: UnsafeMutablePointer<JNIEnv?>!, thisClass: jclass) -> jobject? {
return SwiftModule.function().getJNILocalRefValue(in: environment)
}
"""
]
)
}

@Test
func functionReturnArray_javaBindings() throws {
try assertOutput(
input: "public func function() -> [JavaLong]",
.jni,
.java,
javaClassLookupTable: classLookupTable,
expectedChunks: [
"""
/**
* Downcall to Swift:
* {@snippet lang=swift :
* public func function() -> [JavaLong]
* }
*/
public static java.lang.Long[] function() {
return SwiftModule.$function();
}
""",
"""
private static native java.lang.Long[] $function();
""",
]
)
}

@Test
func functionReturnArray_swiftThunks() throws {
try assertOutput(
input: "public func function() -> [JavaLong]",
.jni,
.swift,
detectChunkByInitialLines: 1,
javaClassLookupTable: classLookupTable,
expectedChunks: [
"""
@_cdecl("Java_com_example_swift_SwiftModule__00024function__")
public func Java_com_example_swift_SwiftModule__00024function__(environment: UnsafeMutablePointer<JNIEnv?>!, thisClass: jclass) -> jobjectArray? {
return SwiftModule.function().getJNILocalRefValue(in: environment)
}
"""
]
)
}
}