Skip to content

Commit 6b9c789

Browse files
committed
add struct tests
1 parent 5ed029d commit 6b9c789

File tree

4 files changed

+277
-0
lines changed

4 files changed

+277
-0
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2024 Apple Inc. and the Swift.org project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of Swift.org project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
public struct MySwiftStruct {
16+
private var cap: Int64
17+
public var len: Int64
18+
19+
public init(cap: Int64, len: Int64) {
20+
self.cap = cap
21+
self.len = len
22+
}
23+
24+
public func getCapacity() -> Int64 {
25+
self.cap
26+
}
27+
28+
public mutating func increaseCap(by value: Int64) -> Int64 {
29+
precondition(value > 0)
30+
self.cap += value
31+
return self.cap
32+
}
33+
}

Samples/JExtractJNISampleApp/src/main/java/com/example/swift/HelloJava2SwiftJNI.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,12 @@ static void examples() {
5252
} catch (Exception e) {
5353
System.out.println("Caught exception: " + e.getMessage());
5454
}
55+
56+
MySwiftStruct myStruct = MySwiftStruct.init(12, 34, arena);
57+
System.out.println("myStruct.cap: " + myStruct.getCapacity());
58+
System.out.println("myStruct.len: " + myStruct.getLen());
59+
myStruct.increaseCap(10);
60+
System.out.println("myStruct.cap after increase: " + myStruct.getCapacity());
5561
}
5662

5763
System.out.println("DONE.");
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2024 Apple Inc. and the Swift.org project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of Swift.org project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
package com.example.swift;
16+
17+
import org.junit.jupiter.api.Test;
18+
import org.swift.swiftkit.core.ConfinedSwiftMemorySession;
19+
20+
import static org.junit.jupiter.api.Assertions.*;
21+
22+
public class MySwiftStructTest {
23+
@Test
24+
void init() {
25+
try (var arena = new ConfinedSwiftMemorySession()) {
26+
MySwiftStruct s = MySwiftStruct.init(1337, 42, arena);
27+
assertEquals(1337, s.getCapacity());
28+
assertEquals(42, s.getLen());
29+
}
30+
}
31+
32+
@Test
33+
void getAndSetLen() {
34+
try (var arena = new ConfinedSwiftMemorySession()) {
35+
MySwiftStruct s = MySwiftStruct.init(1337, 42, arena);
36+
s.setLen(100);
37+
assertEquals(100, s.getLen());
38+
}
39+
}
40+
41+
@Test
42+
void increaseCap() {
43+
try (var arena = new ConfinedSwiftMemorySession()) {
44+
MySwiftStruct s = MySwiftStruct.init(1337, 42, arena);
45+
long newCap = s.increaseCap(10);
46+
assertEquals(1347, newCap);
47+
assertEquals(1347, s.getCapacity());
48+
}
49+
}
50+
}
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2025 Apple Inc. and the Swift.org project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of Swift.org project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
import JExtractSwiftLib
16+
import Testing
17+
18+
@Suite
19+
struct JNIStructTests {
20+
let source = """
21+
public struct MyStruct {
22+
let x: Int64
23+
let y: Int64
24+
25+
public init(x: Int64, y: Int64) {
26+
self.x = y
27+
self.y = y
28+
}
29+
30+
public func doSomething(x: Int64) {}
31+
}
32+
"""
33+
34+
@Test
35+
func generatesJavaClass() throws {
36+
try assertOutput(input: source, .jni, .java, expectedChunks: [
37+
"""
38+
// Generated by jextract-swift
39+
// Swift module: SwiftModule
40+
41+
package com.example.swift;
42+
43+
import org.swift.swiftkit.core.*;
44+
import org.swift.swiftkit.core.util.*;
45+
46+
public final class MyStruct extends JNISwiftInstance {
47+
static final String LIB_NAME = "SwiftModule";
48+
49+
@SuppressWarnings("unused")
50+
private static final boolean INITIALIZED_LIBS = initializeLibs();
51+
static boolean initializeLibs() {
52+
System.loadLibrary(LIB_NAME);
53+
return true;
54+
}
55+
56+
public MyStruct(long selfPointer, SwiftArena swiftArena) {
57+
super(selfPointer, swiftArena);
58+
}
59+
""",
60+
"""
61+
private static native void $destroy(long selfPointer);
62+
""",
63+
"""
64+
@Override
65+
protected Runnable $createDestroyFunction() {
66+
long $selfPointer = this.pointer();
67+
return new Runnable() {
68+
@Override
69+
public void run() {
70+
MyStruct.$destroy($selfPointer);
71+
}
72+
};
73+
}
74+
"""
75+
])
76+
}
77+
78+
@Test
79+
func initializer_javaBindings() throws {
80+
try assertOutput(
81+
input: source,
82+
.jni,
83+
.java,
84+
expectedChunks: [
85+
"""
86+
/**
87+
* Downcall to Swift:
88+
* {@snippet lang=swift :
89+
* public init(x: Int64, y: Int64)
90+
* }
91+
*/
92+
public static MyStruct init(long x, long y, SwiftArena swiftArena$) {
93+
long selfPointer = MyStruct.allocatingInit(x, y);
94+
return new MyStruct(selfPointer, swiftArena$);
95+
}
96+
""",
97+
"""
98+
private static native long allocatingInit(long x, long y);
99+
""",
100+
]
101+
)
102+
}
103+
104+
@Test
105+
func initializer_swiftThunks() throws {
106+
try assertOutput(
107+
input: source,
108+
.jni,
109+
.swift,
110+
detectChunkByInitialLines: 1,
111+
expectedChunks: [
112+
"""
113+
@_cdecl("Java_com_example_swift_MyStruct_allocatingInit__JJ")
114+
func Java_com_example_swift_MyStruct_allocatingInit__JJ(environment: UnsafeMutablePointer<JNIEnv?>!, thisClass: jclass, x: jlong, y: jlong) -> jlong {
115+
let selfPointer = UnsafeMutablePointer<MyStruct>.allocate(capacity: 1)
116+
selfPointer.initialize(to: MyStruct(x: Int64(fromJNI: x, in: environment!), y: Int64(fromJNI: y, in: environment!)))
117+
return Int64(Int(bitPattern: selfPointer)).getJNIValue(in: environment)
118+
}
119+
"""
120+
]
121+
)
122+
}
123+
124+
@Test
125+
func destroyFunction_swiftThunks() throws {
126+
try assertOutput(
127+
input: source,
128+
.jni,
129+
.swift,
130+
detectChunkByInitialLines: 1,
131+
expectedChunks: [
132+
"""
133+
@_cdecl("Java_com_example_swift_MyStruct__00024destroy__J")
134+
func Java_com_example_swift_MyStruct__00024destroy__J(environment: UnsafeMutablePointer<JNIEnv?>!, thisClass: jclass, selfPointer: jlong) {
135+
let pointer = UnsafeMutablePointer<MyStruct>(bitPattern: Int(Int64(fromJNI: selfPointer, in: environment!)))!
136+
pointer.deinitialize(count: 1)
137+
pointer.deallocate()
138+
}
139+
"""
140+
]
141+
)
142+
}
143+
144+
@Test
145+
func memberMethod_javaBindings() throws {
146+
try assertOutput(
147+
input: source,
148+
.jni,
149+
.java,
150+
expectedChunks: [
151+
"""
152+
/**
153+
* Downcall to Swift:
154+
* {@snippet lang=swift :
155+
* public func doSomething(x: Int64)
156+
* }
157+
*/
158+
public void doSomething(long x) {
159+
long selfPointer = this.pointer();
160+
MyStruct.$doSomething(x, selfPointer);
161+
}
162+
""",
163+
"""
164+
private static native void $doSomething(long x, long selfPointer);
165+
"""
166+
]
167+
)
168+
}
169+
170+
@Test
171+
func memberMethod_swiftThunks() throws {
172+
try assertOutput(
173+
input: source,
174+
.jni,
175+
.swift,
176+
detectChunkByInitialLines: 1,
177+
expectedChunks: [
178+
"""
179+
@_cdecl("Java_com_example_swift_MyStruct__00024doSomething__JJ")
180+
func Java_com_example_swift_MyStruct__00024doSomething__JJ(environment: UnsafeMutablePointer<JNIEnv?>!, thisClass: jclass, x: jlong, selfPointer: jlong) {
181+
let self$ = UnsafeMutablePointer<MyStruct>(bitPattern: Int(Int64(fromJNI: selfPointer, in: environment!)))!
182+
self$.pointee.doSomething(x: Int64(fromJNI: x, in: environment!))
183+
}
184+
""",
185+
]
186+
)
187+
}
188+
}

0 commit comments

Comments
 (0)