Skip to content

Commit 29f3d18

Browse files
committed
add support for variables
1 parent 7bec685 commit 29f3d18

File tree

10 files changed

+136
-11
lines changed

10 files changed

+136
-11
lines changed

Samples/JExtractJNISampleApp/Sources/MySwiftLibrary/MySwiftClass.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,25 @@ public class MySwiftClass {
1616
let x: Int64
1717
let y: Int64
1818

19+
public let constant: Int64 = 100
20+
public var mutable: Int64 = 0
21+
public var product: Int64 {
22+
return x * y
23+
}
24+
public var throwingVariable: Int64 {
25+
get throws {
26+
throw MySwiftClassError.swiftError
27+
}
28+
}
29+
public var mutableDividedByTwo: Int64 {
30+
get {
31+
return mutable / 2
32+
}
33+
set {
34+
mutable = newValue * 2
35+
}
36+
}
37+
1938
public static func method() {
2039
p("Hello from static method in a class!")
2140
}

Samples/JExtractJNISampleApp/Sources/MySwiftLibrary/MySwiftLibrary.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
import Darwin.C
2424
#endif
2525

26+
public var globalVariable: Int64 = 0
27+
2628
public func helloWorld() {
2729
p("\(#function)")
2830
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
22
"javaPackage": "com.example.swift",
3-
"mode": "jni"
3+
"mode": "jni",
44
}

Samples/JExtractJNISampleApp/src/test/java/com/example/swift/MySwiftClassTest.java

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,55 @@ void throwingFunction() {
6161
assertEquals("swiftError", exception.getMessage());
6262
}
6363
}
64+
65+
@Test
66+
void constant() {
67+
try (var arena = new ConfinedSwiftMemorySession(Thread.currentThread())) {
68+
MySwiftClass c = MySwiftClass.init(20, 10, arena);
69+
assertEquals(100, c.getConstant());
70+
}
71+
}
72+
73+
@Test
74+
void mutable() {
75+
try (var arena = new ConfinedSwiftMemorySession(Thread.currentThread())) {
76+
MySwiftClass c = MySwiftClass.init(20, 10, arena);
77+
assertEquals(0, c.getMutable());
78+
c.setMutable(42);
79+
assertEquals(42, c.getMutable());
80+
}
81+
}
82+
83+
@Test
84+
void product() {
85+
try (var arena = new ConfinedSwiftMemorySession(Thread.currentThread())) {
86+
MySwiftClass c = MySwiftClass.init(20, 10, arena);
87+
assertEquals(200, c.getProduct());
88+
}
89+
}
90+
91+
@Test
92+
void throwingVariable() {
93+
try (var arena = new ConfinedSwiftMemorySession(Thread.currentThread())) {
94+
MySwiftClass c = MySwiftClass.init(20, 10, arena);
95+
96+
Exception exception = assertThrows(Exception.class, () -> c.getThrowingVariable());
97+
98+
assertEquals("swiftError", exception.getMessage());
99+
}
100+
}
101+
102+
@Test
103+
void mutableDividedByTwo() {
104+
try (var arena = new ConfinedSwiftMemorySession(Thread.currentThread())) {
105+
MySwiftClass c = MySwiftClass.init(20, 10, arena);
106+
assertEquals(0, c.getMutableDividedByTwo());
107+
c.setMutable(20);
108+
assertEquals(10, c.getMutableDividedByTwo());
109+
c.setMutableDividedByTwo(5);
110+
assertEquals(10, c.getMutable());
111+
}
112+
}
113+
114+
64115
}

Samples/JExtractJNISampleApp/src/test/java/com/example/swift/MySwiftLibraryTest.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,11 @@ void call_writeString_jextract() {
5454

5555
assertEquals(string.length(), reply);
5656
}
57+
58+
@Test
59+
void globalVariable() {
60+
assertEquals(0, MySwiftLibrary.getGlobalVariable());
61+
MySwiftLibrary.setGlobalVariable(100);
62+
assertEquals(100, MySwiftLibrary.getGlobalVariable());
63+
}
5764
}

Sources/JExtractSwiftLib/ImportedDecls.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ public final class ImportedFunc: ImportedDecl, CustomStringConvertible {
9191
}
9292
return false
9393
}
94-
94+
9595
/// If this function/method is member of a class/struct/protocol,
9696
/// this will contain that declaration's imported name.
9797
///

Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaBindingsPrinting.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ extension JNISwift2JavaGenerator {
7979
printFunctionBinding(&printer, decl)
8080
printer.println()
8181
}
82+
83+
for decl in analysis.importedGlobalVariables {
84+
printFunctionBinding(&printer, decl)
85+
printer.println()
86+
}
8287
}
8388
}
8489

@@ -113,10 +118,17 @@ extension JNISwift2JavaGenerator {
113118

114119
for initializer in decl.initializers {
115120
printInitializerBindings(&printer, initializer, type: decl)
121+
printer.println()
116122
}
117123

118124
for method in decl.methods {
119125
printFunctionBinding(&printer, method)
126+
printer.println()
127+
}
128+
129+
for variable in decl.variables {
130+
printFunctionBinding(&printer, variable)
131+
printer.println()
120132
}
121133

122134
printDestroyFunction(&printer, decl)

Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaTranslation.swift

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,15 @@ extension JNISwift2JavaGenerator {
3737
// Types with no parent will be outputted inside a "module" class.
3838
let parentName = decl.parentType?.asNominalType?.nominalTypeDecl.qualifiedName ?? swiftModuleName
3939

40+
// Name.
41+
let javaName = switch decl.apiKind {
42+
case .getter: "get\(decl.name.toCamelCase)"
43+
case .setter: "set\(decl.name.toCamelCase)"
44+
case .function, .initializer: decl.name
45+
}
46+
4047
return TranslatedFunctionDecl(
41-
name: decl.name,
48+
name: javaName,
4249
parentName: parentName,
4350
translatedFunctionSignature: translatedFunctionSignature
4451
)

Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+SwiftThunkPrinting.swift

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,11 @@ extension JNISwift2JavaGenerator {
8787
printSwiftFunctionThunk(&printer, decl)
8888
printer.println()
8989
}
90+
91+
for decl in analysis.importedGlobalVariables {
92+
printSwiftFunctionThunk(&printer, decl)
93+
printer.println()
94+
}
9095
}
9196

9297
private func printNominalTypeThunks(_ printer: inout CodePrinter, _ type: ImportedNominalType) throws {
@@ -102,6 +107,11 @@ extension JNISwift2JavaGenerator {
102107
printer.println()
103108
}
104109

110+
for variable in type.variables {
111+
printSwiftFunctionThunk(&printer, variable)
112+
printer.println()
113+
}
114+
105115
printDestroyFunctionThunk(&printer, type)
106116
}
107117

@@ -192,19 +202,32 @@ extension JNISwift2JavaGenerator {
192202
let translatedDecl = self.translatedDecl(for: decl)
193203
let swiftReturnType = decl.functionSignature.result.type
194204

195-
let downcallParameters = renderDowncallArguments(
196-
swiftFunctionSignature: decl.functionSignature,
197-
translatedFunctionSignature: translatedDecl.translatedFunctionSignature
198-
)
199205
let tryClause: String = decl.isThrowing ? "try " : ""
200-
let functionDowncall = "\(tryClause)\(calleeName).\(decl.name)(\(downcallParameters))"
206+
207+
let result: String
208+
switch decl.apiKind {
209+
case .function, .initializer:
210+
let downcallParameters = renderDowncallArguments(
211+
swiftFunctionSignature: decl.functionSignature,
212+
translatedFunctionSignature: translatedDecl.translatedFunctionSignature
213+
)
214+
result = "\(tryClause)\(calleeName).\(decl.name)(\(downcallParameters))"
215+
216+
case .getter:
217+
result = "\(tryClause)\(calleeName).\(decl.name)"
218+
219+
case .setter:
220+
assert(decl.functionSignature.parameters.count == 1)
221+
let newValueParameter = decl.functionSignature.parameters[0]
222+
result = "\(calleeName).\(decl.name) = \(renderJNIToSwiftConversion("newValue", type: newValueParameter.type))"
223+
}
201224

202225
let returnStatement =
203226
if swiftReturnType.isVoid {
204-
functionDowncall
227+
result
205228
} else {
206229
"""
207-
let result = \(functionDowncall)
230+
let result = \(result)
208231
return result.getJNIValue(in: environment)
209232
"""
210233
}
@@ -320,6 +343,10 @@ extension JNISwift2JavaGenerator {
320343
}
321344
.joined(separator: ", ")
322345
}
346+
347+
private func renderJNIToSwiftConversion(_ variableName: String, type: SwiftType) -> String {
348+
"\(type)(fromJNI: \(variableName), in: environment!)"
349+
}
323350
}
324351

325352
extension String {

Sources/JExtractSwiftLib/SwiftTypes/SwiftFunctionSignature.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ extension VariableDeclSyntax {
254254
/// - Parameters:
255255
/// - binding the pattern binding in this declaration.
256256
func supportedAccessorKinds(binding: PatternBindingSyntax) -> SupportedAccessorKinds {
257-
if self.bindingSpecifier == .keyword(.let) {
257+
if self.bindingSpecifier.tokenKind == .keyword(.let) {
258258
return [.get]
259259
}
260260

0 commit comments

Comments
 (0)