Skip to content

Commit da7d0a5

Browse files
sidepelicanktoso
andauthored
jextract/jni: Refactor toString generation to use the standard method generation path (#567)
* Include toString function generation in the common method generation path * swift format * case synthesizedFunction(SynthesizedAPI) * dont change parameter name to self --------- Co-authored-by: Konrad Malawski <ktoso@apple.com>
1 parent 243e487 commit da7d0a5

8 files changed

Lines changed: 76 additions & 82 deletions

Sources/JExtractSwiftLib/FFM/CDeclLowering/FFMSwift2JavaGenerator+FunctionLowering.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -993,6 +993,14 @@ extension LoweredFunctionSignature {
993993
.joined(separator: ", ")
994994
resultExpr = "\(callee)(\(raw: arguments))"
995995

996+
case .synthesizedFunction(let function):
997+
switch function {
998+
case .toString:
999+
resultExpr = "String(describing: \(callee))"
1000+
case .toDebugString:
1001+
resultExpr = "String(reflecting: \(callee))"
1002+
}
1003+
9961004
case .getter:
9971005
assert(paramExprs.isEmpty)
9981006
resultExpr = callee

Sources/JExtractSwiftLib/FFM/FFMSwift2JavaGenerator+JavaTranslation.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ extension FFMSwift2JavaGenerator {
160160
switch decl.apiKind {
161161
case .getter, .subscriptGetter: decl.javaGetterName
162162
case .setter, .subscriptSetter: decl.javaSetterName
163-
case .function, .initializer, .enumCase: decl.name
163+
case .function, .synthesizedFunction, .initializer, .enumCase: decl.name
164164
}
165165

166166
// Signature.

Sources/JExtractSwiftLib/ImportedDecls.swift

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,14 @@ import SwiftSyntax
1717
/// Any imported (Swift) declaration
1818
protocol ImportedDecl: AnyObject {}
1919

20-
package enum SwiftAPIKind {
20+
package enum SynthesizedAPI: Equatable {
21+
case toString
22+
case toDebugString
23+
}
24+
25+
package enum SwiftAPIKind: Equatable {
2126
case function
27+
case synthesizedFunction(SynthesizedAPI)
2228
case initializer
2329
case getter
2430
case setter
@@ -182,7 +188,7 @@ public final class ImportedFunc: ImportedDecl, CustomStringConvertible {
182188
case .getter: "getter:"
183189
case .setter: "setter:"
184190
case .enumCase: "case:"
185-
case .function, .initializer: ""
191+
case .function, .synthesizedFunction, .initializer: ""
186192
case .subscriptGetter: "subscriptGetter:"
187193
case .subscriptSetter: "subscriptSetter:"
188194
}

Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaBindingsPrinting.swift

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -267,9 +267,6 @@ extension JNISwift2JavaGenerator {
267267
printer.println()
268268
}
269269

270-
printToStringMethods(&printer, decl)
271-
printer.println()
272-
273270
printSpecificTypeHelpers(&printer, decl)
274271

275272
printTypeMetadataAddressFunction(&printer, decl)
@@ -294,28 +291,6 @@ extension JNISwift2JavaGenerator {
294291
}
295292
}
296293

297-
private func printToStringMethods(_ printer: inout CodePrinter, _ decl: ImportedNominalType) {
298-
printer.printBraceBlock("public String toString()") { printer in
299-
printer.print(
300-
"""
301-
return $toString(this.$memoryAddress());
302-
"""
303-
)
304-
}
305-
printer.print("private static native java.lang.String $toString(long selfPointer);")
306-
307-
printer.println()
308-
309-
printer.printBraceBlock("public String toDebugString()") { printer in
310-
printer.print(
311-
"""
312-
return $toDebugString(this.$memoryAddress());
313-
"""
314-
)
315-
}
316-
printer.print("private static native java.lang.String $toDebugString(long selfPointer);")
317-
}
318-
319294
private func printHeader(_ printer: inout CodePrinter) {
320295
printer.print(
321296
"""

Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaTranslation.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ extension JNISwift2JavaGenerator {
213213
switch decl.apiKind {
214214
case .getter, .subscriptGetter: decl.javaGetterName
215215
case .setter, .subscriptSetter: decl.javaSetterName
216-
case .function, .initializer, .enumCase: decl.name
216+
case .function, .synthesizedFunction, .initializer, .enumCase: decl.name
217217
}
218218

219219
// Swift -> Java

Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+SwiftThunkPrinting.swift

Lines changed: 8 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,6 @@ extension JNISwift2JavaGenerator {
271271
printer.println()
272272
}
273273

274-
printToStringMethods(&printer, type)
275274
printSpecificTypeThunks(&printer, type)
276275
printTypeMetadataAddressThunk(&printer, type)
277276
printer.println()
@@ -286,49 +285,6 @@ extension JNISwift2JavaGenerator {
286285
try printSwiftInterfaceWrapper(&printer, protocolWrapper)
287286
}
288287

289-
private func printToStringMethods(_ printer: inout CodePrinter, _ type: ImportedNominalType) {
290-
let selfPointerParam = JavaParameter(name: "selfPointer", type: .long)
291-
let parentName = type.qualifiedName
292-
293-
printCDecl(
294-
&printer,
295-
javaMethodName: "$toString",
296-
parentName: type.swiftNominal.qualifiedName,
297-
parameters: [
298-
selfPointerParam
299-
],
300-
resultType: .javaLangString
301-
) { printer in
302-
let selfVar = self.printSelfJLongToUnsafeMutablePointer(&printer, swiftParentName: parentName, selfPointerParam)
303-
304-
printer.print(
305-
"""
306-
return String(describing: \(selfVar).pointee).getJNIValue(in: environment)
307-
"""
308-
)
309-
}
310-
311-
printer.println()
312-
313-
printCDecl(
314-
&printer,
315-
javaMethodName: "$toDebugString",
316-
parentName: type.swiftNominal.qualifiedName,
317-
parameters: [
318-
selfPointerParam
319-
],
320-
resultType: .javaLangString
321-
) { printer in
322-
let selfVar = self.printSelfJLongToUnsafeMutablePointer(&printer, swiftParentName: parentName, selfPointerParam)
323-
324-
printer.print(
325-
"""
326-
return String(reflecting: \(selfVar).pointee).getJNIValue(in: environment)
327-
"""
328-
)
329-
}
330-
}
331-
332288
private func printEnumDiscriminator(_ printer: inout CodePrinter, _ type: ImportedNominalType) {
333289
let selfPointerParam = JavaParameter(name: "selfPointer", type: .long)
334290
printCDecl(
@@ -623,6 +579,14 @@ extension JNISwift2JavaGenerator {
623579
.joined(separator: ", ")
624580
result = "\(tryClause)\(callee).\(decl.name)(\(downcallArguments))"
625581

582+
case .synthesizedFunction(let function):
583+
switch function {
584+
case .toString:
585+
result = "String(describing: \(callee))"
586+
case .toDebugString:
587+
result = "String(reflecting: \(callee))"
588+
}
589+
626590
case .enumCase:
627591
let downcallArguments = zip(
628592
decl.functionSignature.parameters,

Sources/JExtractSwiftLib/Swift2JavaVisitor.swift

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ final class Swift2JavaVisitor {
8585
for memberItem in node.memberBlock.members {
8686
self.visit(decl: memberItem.decl, in: importedNominalType, sourceFilePath: sourceFilePath)
8787
}
88+
89+
self.synthesizeToStringMethods(in: importedNominalType)
8890
}
8991

9092
func visit(
@@ -405,6 +407,46 @@ final class Swift2JavaVisitor {
405407
}
406408
}
407409
}
410+
411+
private func synthesizeToStringMethods(in imported: ImportedNominalType) {
412+
switch imported.swiftNominal.kind {
413+
case .actor, .class, .enum, .struct:
414+
break
415+
case .protocol:
416+
return
417+
}
418+
419+
let knownTypes = SwiftKnownTypes(symbolTable: translator.symbolTable)
420+
let toStringFunctionSignature = SwiftFunctionSignature(
421+
selfParameter: .instance(SwiftParameter(convention: .byValue, parameterName: "selfPointer", type: imported.swiftType)),
422+
parameters: [],
423+
result: SwiftResult(convention: .direct, type: knownTypes.string),
424+
effectSpecifiers: [],
425+
genericParameters: [],
426+
genericRequirements: []
427+
)
428+
429+
func makeToStringFunc(name: String, kind: SwiftAPIKind) -> ImportedFunc {
430+
ImportedFunc(
431+
module: translator.swiftModuleName,
432+
swiftDecl: DeclSyntax("func \(raw: name)() -> String"),
433+
name: name,
434+
apiKind: kind,
435+
functionSignature: toStringFunctionSignature
436+
)
437+
}
438+
439+
if !imported.methods.contains(where: {
440+
$0.name == "toString" && $0.functionSignature == toStringFunctionSignature
441+
}) {
442+
imported.methods.append(makeToStringFunc(name: "toString", kind: .synthesizedFunction(.toString)))
443+
}
444+
if !imported.methods.contains(where: {
445+
$0.name == "toDebugString" && $0.functionSignature == toStringFunctionSignature
446+
}) {
447+
imported.methods.append(makeToStringFunc(name: "toDebugString", kind: .synthesizedFunction(.toDebugString)))
448+
}
449+
}
408450
}
409451

410452
extension DeclSyntaxProtocol where Self: WithModifiersSyntax & WithAttributesSyntax {

Tests/JExtractSwiftTests/JNI/JNIToStringTests.swift

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,11 @@ struct JNIToStringTests {
3232
detectChunkByInitialLines: 1,
3333
expectedChunks: [
3434
"""
35-
public String toString() {
36-
return $toString(this.$memoryAddress());
35+
public java.lang.String toString() {
36+
return MyType.$toString(this.$memoryAddress());
3737
}
38-
""",
39-
"""
4038
private static native java.lang.String $toString(long selfPointer);
41-
""",
39+
"""
4240
]
4341
)
4442
}
@@ -55,7 +53,7 @@ struct JNIToStringTests {
5553
@_cdecl("Java_com_example_swift_MyType__00024toString__J")
5654
public func Java_com_example_swift_MyType__00024toString__J(environment: UnsafeMutablePointer<JNIEnv?>!, thisClass: jclass, selfPointer: jlong) -> jstring? {
5755
...
58-
return String(describing: self$.pointee).getJNIValue(in: environment)
56+
return String(describing: selfPointer$.pointee).getJNIValue(in: environment)
5957
}
6058
"""
6159
]
@@ -71,9 +69,10 @@ struct JNIToStringTests {
7169
detectChunkByInitialLines: 1,
7270
expectedChunks: [
7371
"""
74-
public String toDebugString() {
75-
return $toDebugString(this.$memoryAddress());
72+
public java.lang.String toDebugString() {
73+
return MyType.$toDebugString(this.$memoryAddress());
7674
}
75+
private static native java.lang.String $toDebugString(long selfPointer);
7776
"""
7877
]
7978
)
@@ -91,7 +90,7 @@ struct JNIToStringTests {
9190
@_cdecl("Java_com_example_swift_MyType__00024toDebugString__J")
9291
public func Java_com_example_swift_MyType__00024toDebugString__J(environment: UnsafeMutablePointer<JNIEnv?>!, thisClass: jclass, selfPointer: jlong) -> jstring? {
9392
...
94-
return String(reflecting: self$.pointee).getJNIValue(in: environment)
93+
return String(reflecting: selfPointer$.pointee).getJNIValue(in: environment)
9594
}
9695
"""
9796
]

0 commit comments

Comments
 (0)