Skip to content

Commit 86da9ee

Browse files
authored
[JExtract/JNI] Fix boolean naming for variables already called isX (#325)
1 parent a82196e commit 86da9ee

File tree

4 files changed

+100
-9
lines changed

4 files changed

+100
-9
lines changed

Sources/JExtractSwiftLib/Convenience/String+Extensions.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@
1414

1515
extension String {
1616

17-
// TODO: naive implementation good enough for our simple case `methodMethodSomething` -> `MethodSomething`
18-
var toCamelCase: String {
17+
var firstCharacterUppercased: String {
1918
guard let f = first else {
2019
return self
2120
}

Sources/JExtractSwiftLib/ImportedDecls.swift

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -160,15 +160,25 @@ extension ImportedFunc {
160160
let returnsBoolean = self.functionSignature.result.type.asNominalTypeDeclaration?.knownTypeKind == .bool
161161

162162
if !returnsBoolean {
163-
return "get\(self.name.toCamelCase)"
163+
return "get\(self.name.firstCharacterUppercased)"
164164
} else if !self.name.hasJavaBooleanNamingConvention {
165-
return "is\(self.name.toCamelCase)"
165+
return "is\(self.name.firstCharacterUppercased)"
166166
} else {
167-
return self.name.toCamelCase
167+
return self.name
168168
}
169169
}
170170

171171
var javaSetterName: String {
172-
"set\(self.name.toCamelCase)"
172+
let isBooleanSetter = self.functionSignature.parameters.first?.type.asNominalTypeDeclaration?.knownTypeKind == .bool
173+
174+
// If the variable is already named "isX", then we make
175+
// the setter "setX" to match beans spec.
176+
if isBooleanSetter && self.name.hasJavaBooleanNamingConvention {
177+
// Safe to force unwrap due to `hasJavaBooleanNamingConvention` check.
178+
let propertyName = self.name.split(separator: "is", maxSplits: 1).last!
179+
return "set\(propertyName)"
180+
} else {
181+
return "set\(self.name.firstCharacterUppercased)"
182+
}
173183
}
174184
}

Tests/JExtractSwiftTests/Asserts/TextAssertions.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,6 @@ func assertOutput(
115115
print("==== ---------------------------------------------------------------")
116116

117117
#expect(output.contains(expectedChunk), sourceLocation: sourceLocation)
118-
fatalError("Failed: \(filePath):\(line)")
119118
continue
120119
}
121120

Tests/JExtractSwiftTests/JNI/JNIVariablesTests.swift

Lines changed: 85 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ struct JNIVariablesTests {
3333
set { }
3434
}
3535
public var someBoolean: Bool
36-
public let isBoolean: Bool
36+
public var isBoolean: Bool
3737
}
3838
"""
3939

@@ -411,7 +411,7 @@ struct JNIVariablesTests {
411411
}
412412

413413
@Test
414-
func boolean_swiftThunks() throws {
414+
func someBoolean_swiftThunks() throws {
415415
try assertOutput(
416416
input: membersSource,
417417
.jni,
@@ -450,4 +450,87 @@ struct JNIVariablesTests {
450450
]
451451
)
452452
}
453+
454+
@Test
455+
func isBoolean_javaBindings() throws {
456+
try assertOutput(
457+
input: membersSource,
458+
.jni,
459+
.java,
460+
detectChunkByInitialLines: 8,
461+
expectedChunks: [
462+
"""
463+
/**
464+
* Downcall to Swift:
465+
* {@snippet lang=swift :
466+
* public var isBoolean: Bool
467+
* }
468+
*/
469+
public boolean isBoolean() {
470+
long self$ = this.$memoryAddress();
471+
return MyClass.$isBoolean(self$);
472+
}
473+
""",
474+
"""
475+
/**
476+
* Downcall to Swift:
477+
* {@snippet lang=swift :
478+
* public var isBoolean: Bool
479+
* }
480+
*/
481+
public void setBoolean(boolean newValue) {
482+
long self$ = this.$memoryAddress();
483+
MyClass.$setBoolean(newValue, self$);
484+
}
485+
""",
486+
"""
487+
private static native boolean $isBoolean(long selfPointer);
488+
""",
489+
"""
490+
private static native void $setBoolean(boolean newValue, long selfPointer);
491+
"""
492+
]
493+
)
494+
}
495+
496+
@Test
497+
func isBoolean_swiftThunks() throws {
498+
try assertOutput(
499+
input: membersSource,
500+
.jni,
501+
.swift,
502+
detectChunkByInitialLines: 1,
503+
expectedChunks: [
504+
"""
505+
@_cdecl("Java_com_example_swift_MyClass__00024isBoolean__J")
506+
func Java_com_example_swift_MyClass__00024isBoolean__J(environment: UnsafeMutablePointer<JNIEnv?>!, thisClass: jclass, selfPointer: jlong) -> jboolean {
507+
guard let env$ = environment else {
508+
fatalError("Missing JNIEnv in downcall to \\(#function)")
509+
}
510+
assert(selfPointer != 0, "selfPointer memory address was null")
511+
let selfBits$ = Int(Int64(fromJNI: selfPointer, in: env$))
512+
guard let self$ = UnsafeMutablePointer<MyClass>(bitPattern: selfBits$) else {
513+
fatalError("self memory address was null in call to \\(#function)!")
514+
}
515+
let result = self$.pointee.isBoolean
516+
return result.getJNIValue(in: environment)
517+
}
518+
""",
519+
"""
520+
@_cdecl("Java_com_example_swift_MyClass__00024setBoolean__ZJ")
521+
func Java_com_example_swift_MyClass__00024setBoolean__ZJ(environment: UnsafeMutablePointer<JNIEnv?>!, thisClass: jclass, newValue: jboolean, selfPointer: jlong) {
522+
guard let env$ = environment else {
523+
fatalError("Missing JNIEnv in downcall to \\(#function)")
524+
}
525+
assert(selfPointer != 0, "selfPointer memory address was null")
526+
let selfBits$ = Int(Int64(fromJNI: selfPointer, in: env$))
527+
guard let self$ = UnsafeMutablePointer<MyClass>(bitPattern: selfBits$) else {
528+
fatalError("self memory address was null in call to \\(#function)!")
529+
}
530+
self$.pointee.isBoolean = Bool(fromJNI: newValue, in: environment!)
531+
}
532+
"""
533+
]
534+
)
535+
}
453536
}

0 commit comments

Comments
 (0)