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 @@ -993,6 +993,14 @@ extension LoweredFunctionSignature {
.joined(separator: ", ")
resultExpr = "\(callee)(\(raw: arguments))"

case .synthesizedFunction(let function):
switch function {
case .toString:
resultExpr = "String(describing: \(callee))"
case .toDebugString:
resultExpr = "String(reflecting: \(callee))"
}

case .getter:
assert(paramExprs.isEmpty)
resultExpr = callee
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ extension FFMSwift2JavaGenerator {
switch decl.apiKind {
case .getter, .subscriptGetter: decl.javaGetterName
case .setter, .subscriptSetter: decl.javaSetterName
case .function, .initializer, .enumCase: decl.name
case .function, .synthesizedFunction, .initializer, .enumCase: decl.name
}

// Signature.
Expand Down
10 changes: 8 additions & 2 deletions Sources/JExtractSwiftLib/ImportedDecls.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,14 @@ import SwiftSyntax
/// Any imported (Swift) declaration
protocol ImportedDecl: AnyObject {}

package enum SwiftAPIKind {
package enum SynthesizedAPI: Equatable {
case toString
case toDebugString
}

package enum SwiftAPIKind: Equatable {
case function
case synthesizedFunction(SynthesizedAPI)
case initializer
case getter
case setter
Expand Down Expand Up @@ -182,7 +188,7 @@ public final class ImportedFunc: ImportedDecl, CustomStringConvertible {
case .getter: "getter:"
case .setter: "setter:"
case .enumCase: "case:"
case .function, .initializer: ""
case .function, .synthesizedFunction, .initializer: ""
case .subscriptGetter: "subscriptGetter:"
case .subscriptSetter: "subscriptSetter:"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -267,9 +267,6 @@ extension JNISwift2JavaGenerator {
printer.println()
}

printToStringMethods(&printer, decl)
printer.println()

printSpecificTypeHelpers(&printer, decl)

printTypeMetadataAddressFunction(&printer, decl)
Expand All @@ -294,28 +291,6 @@ extension JNISwift2JavaGenerator {
}
}

private func printToStringMethods(_ printer: inout CodePrinter, _ decl: ImportedNominalType) {
printer.printBraceBlock("public String toString()") { printer in
printer.print(
"""
return $toString(this.$memoryAddress());
"""
)
}
printer.print("private static native java.lang.String $toString(long selfPointer);")

printer.println()

printer.printBraceBlock("public String toDebugString()") { printer in
printer.print(
"""
return $toDebugString(this.$memoryAddress());
"""
)
}
printer.print("private static native java.lang.String $toDebugString(long selfPointer);")
}

private func printHeader(_ printer: inout CodePrinter) {
printer.print(
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ extension JNISwift2JavaGenerator {
switch decl.apiKind {
case .getter, .subscriptGetter: decl.javaGetterName
case .setter, .subscriptSetter: decl.javaSetterName
case .function, .initializer, .enumCase: decl.name
case .function, .synthesizedFunction, .initializer, .enumCase: decl.name
}

// Swift -> Java
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,6 @@ extension JNISwift2JavaGenerator {
printer.println()
}

printToStringMethods(&printer, type)
printSpecificTypeThunks(&printer, type)
printTypeMetadataAddressThunk(&printer, type)
printer.println()
Expand All @@ -286,49 +285,6 @@ extension JNISwift2JavaGenerator {
try printSwiftInterfaceWrapper(&printer, protocolWrapper)
}

private func printToStringMethods(_ printer: inout CodePrinter, _ type: ImportedNominalType) {
let selfPointerParam = JavaParameter(name: "selfPointer", type: .long)
let parentName = type.qualifiedName

printCDecl(
&printer,
javaMethodName: "$toString",
parentName: type.swiftNominal.qualifiedName,
parameters: [
selfPointerParam
],
resultType: .javaLangString
) { printer in
let selfVar = self.printSelfJLongToUnsafeMutablePointer(&printer, swiftParentName: parentName, selfPointerParam)

printer.print(
"""
return String(describing: \(selfVar).pointee).getJNIValue(in: environment)
"""
)
}

printer.println()

printCDecl(
&printer,
javaMethodName: "$toDebugString",
parentName: type.swiftNominal.qualifiedName,
parameters: [
selfPointerParam
],
resultType: .javaLangString
) { printer in
let selfVar = self.printSelfJLongToUnsafeMutablePointer(&printer, swiftParentName: parentName, selfPointerParam)

printer.print(
"""
return String(reflecting: \(selfVar).pointee).getJNIValue(in: environment)
"""
)
}
}

private func printEnumDiscriminator(_ printer: inout CodePrinter, _ type: ImportedNominalType) {
let selfPointerParam = JavaParameter(name: "selfPointer", type: .long)
printCDecl(
Expand Down Expand Up @@ -623,6 +579,14 @@ extension JNISwift2JavaGenerator {
.joined(separator: ", ")
result = "\(tryClause)\(callee).\(decl.name)(\(downcallArguments))"

case .synthesizedFunction(let function):
switch function {
case .toString:
result = "String(describing: \(callee))"
case .toDebugString:
result = "String(reflecting: \(callee))"
}

case .enumCase:
let downcallArguments = zip(
decl.functionSignature.parameters,
Expand Down
42 changes: 42 additions & 0 deletions Sources/JExtractSwiftLib/Swift2JavaVisitor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ final class Swift2JavaVisitor {
for memberItem in node.memberBlock.members {
self.visit(decl: memberItem.decl, in: importedNominalType, sourceFilePath: sourceFilePath)
}

self.synthesizeToStringMethods(in: importedNominalType)
}

func visit(
Expand Down Expand Up @@ -405,6 +407,46 @@ final class Swift2JavaVisitor {
}
}
}

private func synthesizeToStringMethods(in imported: ImportedNominalType) {
switch imported.swiftNominal.kind {
case .actor, .class, .enum, .struct:
break
case .protocol:
return
}

let knownTypes = SwiftKnownTypes(symbolTable: translator.symbolTable)
let toStringFunctionSignature = SwiftFunctionSignature(
selfParameter: .instance(SwiftParameter(convention: .byValue, parameterName: "selfPointer", type: imported.swiftType)),
parameters: [],
result: SwiftResult(convention: .direct, type: knownTypes.string),
effectSpecifiers: [],
genericParameters: [],
genericRequirements: []
)

func makeToStringFunc(name: String, kind: SwiftAPIKind) -> ImportedFunc {
ImportedFunc(
module: translator.swiftModuleName,
swiftDecl: DeclSyntax("func \(raw: name)() -> String"),
name: name,
apiKind: kind,
functionSignature: toStringFunctionSignature
)
}

if !imported.methods.contains(where: {
$0.name == "toString" && $0.functionSignature == toStringFunctionSignature
}) {
imported.methods.append(makeToStringFunc(name: "toString", kind: .synthesizedFunction(.toString)))
}
if !imported.methods.contains(where: {
$0.name == "toDebugString" && $0.functionSignature == toStringFunctionSignature
}) {
imported.methods.append(makeToStringFunc(name: "toDebugString", kind: .synthesizedFunction(.toDebugString)))
}
}
}

extension DeclSyntaxProtocol where Self: WithModifiersSyntax & WithAttributesSyntax {
Expand Down
17 changes: 8 additions & 9 deletions Tests/JExtractSwiftTests/JNI/JNIToStringTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,11 @@ struct JNIToStringTests {
detectChunkByInitialLines: 1,
expectedChunks: [
"""
public String toString() {
return $toString(this.$memoryAddress());
public java.lang.String toString() {
return MyType.$toString(this.$memoryAddress());
}
""",
"""
private static native java.lang.String $toString(long selfPointer);
""",
"""
]
)
}
Expand All @@ -55,7 +53,7 @@ struct JNIToStringTests {
@_cdecl("Java_com_example_swift_MyType__00024toString__J")
public func Java_com_example_swift_MyType__00024toString__J(environment: UnsafeMutablePointer<JNIEnv?>!, thisClass: jclass, selfPointer: jlong) -> jstring? {
...
return String(describing: self$.pointee).getJNIValue(in: environment)
return String(describing: selfPointer$.pointee).getJNIValue(in: environment)
}
"""
]
Expand All @@ -71,9 +69,10 @@ struct JNIToStringTests {
detectChunkByInitialLines: 1,
expectedChunks: [
"""
public String toDebugString() {
return $toDebugString(this.$memoryAddress());
public java.lang.String toDebugString() {
return MyType.$toDebugString(this.$memoryAddress());
}
private static native java.lang.String $toDebugString(long selfPointer);
"""
]
)
Expand All @@ -91,7 +90,7 @@ struct JNIToStringTests {
@_cdecl("Java_com_example_swift_MyType__00024toDebugString__J")
public func Java_com_example_swift_MyType__00024toDebugString__J(environment: UnsafeMutablePointer<JNIEnv?>!, thisClass: jclass, selfPointer: jlong) -> jstring? {
...
return String(reflecting: self$.pointee).getJNIValue(in: environment)
return String(reflecting: selfPointer$.pointee).getJNIValue(in: environment)
}
"""
]
Expand Down
Loading