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 @@ -41,3 +41,7 @@ public func makeBigTuple() -> (
11, 12, 13, 14.0
)
}

public func namedByteArrayTuple() -> (name: [UInt8], another: [UInt8]) {
(name: [1, 2, 3], another: [4, 5])
}
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,15 @@ void makeBigTuple() {
assertEquals(13L, result.$14);
assertEquals(14.0f, result.$15);
}

@Test
void namedByteArrayTuple() {
var result = MySwiftLibrary.namedByteArrayTuple();

assertArrayEquals(new byte[] { 1, 2, 3 }, result.name());
assertArrayEquals(new byte[] { 4, 5 }, result.another());

assertArrayEquals(new byte[] { 1, 2, 3 }, (byte[]) result.$0);
assertArrayEquals(new byte[] { 4, 5 }, (byte[]) result.$1);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1236,8 +1236,19 @@ extension JNISwift2JavaGenerator {
elements: tupleElements
)

// Collect annotations from tuple elements - if any element is @Unsigned,
// propagate that to the method level
var tupleAnnotations: [JavaAnnotation] = []
for element in elements {
let elementAnnotations = getJavaTypeAnnotations(swiftType: element.type, config: config)
for annotation in elementAnnotations where !tupleAnnotations.contains(annotation) {
tupleAnnotations.append(annotation)
}
}

return TranslatedResult(
javaType: javaResultType,
annotations: tupleAnnotations,
outParameters: outParameters,
conversion: javaNativeConversionStep
)
Expand Down Expand Up @@ -1731,10 +1742,18 @@ extension JNISwift2JavaGenerator {
func render(type: JavaType) -> String {
switch self {
case .newArray(let javaType, let size):
"new \(javaType)[\(size)]"
// For array element types like byte[], we need "new byte[size][]"
// not "new byte[][size]"
var baseType = javaType
var extraDimensions = ""
while case .array(let inner) = baseType {
extraDimensions += "[]"
baseType = inner
}
return "new \(baseType)[\(size)]\(extraDimensions)"

case .new:
"new \(type)()"
return "new \(type)()"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,13 @@
* in a method signature corresponds to a Swift {@code UInt64} type, and therefore
* negative values reported by the signed {@code long} should instead be interpreted positive values,
* larger than {@code Long.MAX_VALUE} that are just not representable using a signed {@code long}.
* <p/>
* If this annotation is used on a method, it refers to the return type using an unsigned integer.
*/
@Documented
@Label("Unsigned integer type")
@Description("Value should be interpreted as unsigned data type")
@Target({TYPE_USE, PARAMETER, FIELD})
@Target({TYPE_USE, PARAMETER, FIELD, METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Unsigned {
}
50 changes: 50 additions & 0 deletions Tests/JExtractSwiftTests/JNI/JNIArrayTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -311,4 +311,54 @@ struct JNIArrayTest {
]
)
}

// ==== -----------------------------------------------------------------------
// MARK: Tuples with array elements

@Test("Import: () -> (name: [UInt8], another: [UInt8]) (Java)")
func tupleByteArrays_java() throws {
try assertOutput(
input: "public func namedByteArrayTuple() -> (name: [UInt8], another: [UInt8]) {}",
.jni,
.java,
detectChunkByInitialLines: 1,
expectedChunks: [
"""
@Unsigned
public static LabeledTuple_namedByteArrayTuple_name_another<byte[], byte[]> namedByteArrayTuple() {
byte[][] result_0$ = new byte[1][];
byte[][] result_1$ = new byte[1][];
SwiftModule.$namedByteArrayTuple(result_0$, result_1$);
return new LabeledTuple_namedByteArrayTuple_name_another<byte[], byte[]>(result_0$[0], result_1$[0]);
}
""",
"""
private static native void $namedByteArrayTuple(byte[][] result_0$, byte[][] result_1$);
""",
]
)
}

@Test("Import: () -> (name: [UInt8], another: [UInt8]) (Swift)")
func tupleByteArrays_swift() throws {
try assertOutput(
input: "public func namedByteArrayTuple() -> (name: [UInt8], another: [UInt8]) {}",
.jni,
.swift,
detectChunkByInitialLines: 1,
expectedChunks: [
"""
@_cdecl("Java_com_example_swift_SwiftModule__00024namedByteArrayTuple___3_3B_3_3B")
public func Java_com_example_swift_SwiftModule__00024namedByteArrayTuple___3_3B_3_3B(environment: UnsafeMutablePointer<JNIEnv?>!, thisClass: jclass, result_0$: jobjectArray?, result_1$: jobjectArray?) {
let tupleResult$ = SwiftModule.namedByteArrayTuple()
let element_0_jni$ = tupleResult$.name.getJNILocalRefValue(in: environment)
environment.interface.SetObjectArrayElement(environment, result_0$, 0, element_0_jni$)
let element_1_jni$ = tupleResult$.another.getJNILocalRefValue(in: environment)
environment.interface.SetObjectArrayElement(environment, result_1$, 0, element_1_jni$)
return
}
"""
]
)
}
}
Loading