@@ -125,26 +125,16 @@ extension JNISwift2JavaGenerator {
125125
126126 /// Prints the extension needed to make allow upcalls from Swift to Java for protocols
127127 private func printSwiftInterfaceWrapper( _ printer: inout CodePrinter , _ type: ImportedNominalType ) throws {
128- let safeProtocolName = type. qualifiedName. replacingOccurrences ( of: " . " , with: " _ " )
129- let wrapperName = " SwiftJava \( safeProtocolName) Wrapper "
130-
131- try printer. printBraceBlock ( " final class \( wrapperName) : \( type. qualifiedName) " ) { printer in
132- let javaInterfaceVariableName = " javaInterface "
133- let swiftJavaInterfaceName = " Java \( safeProtocolName) "
134-
135- printer. print (
136- """
137- let \( javaInterfaceVariableName) : \( swiftJavaInterfaceName)
138-
139- init(javaInterface: \( swiftJavaInterfaceName) ) {
140- self. \( javaInterfaceVariableName) = javaInterface
141- }
142- """
143- )
144- printer. println ( )
128+ let wrapperName = type. javaInterfaceSwiftProtocolWrapperName
129+ let javaInterfaceVariableName = " _ \( type. javaInterfaceName. firstCharacterLowercased) Interface "
145130
131+ printer. printBraceBlock ( " protocol \( wrapperName) " ) { printer in
132+ printer. print ( " var \( javaInterfaceVariableName) : \( type. javaInterfaceName) { get } " )
133+ }
134+ printer. println ( )
135+ printer. printBraceBlock ( " extension \( wrapperName) : \( type. qualifiedName) " ) { printer in
146136 for method in type. methods {
147- try printer. printBraceBlock ( method. swiftDecl. signatureString) { printer in
137+ printer. printBraceBlock ( method. swiftDecl. signatureString) { printer in
148138 let methodName = method. name
149139
150140 let parameters = method. functionSignature. parameters. map { parameter in
@@ -164,13 +154,16 @@ extension JNISwift2JavaGenerator {
164154 """
165155 )
166156
167- return " \( parameterName) Class.wrapMemoryAddressUnsafe(selfPointer: Int64(Int(bitPattern: pointer))) "
157+ return " \( parameterName) Class.wrapMemoryAddressUnsafe(Int64(Int(bitPattern: pointer))) "
168158 }
169159
170160 let javaUpcall = " \( javaInterfaceVariableName) . \( methodName) ( \( parameters. joined ( separator: " , " ) ) ) "
171161
162+ let resultType = method. functionSignature. result. type
172163 if !method. functionSignature. result. type. isVoid {
173- guard let importedNominalType = self . asImportedNominalTypeDecl ( type. swiftType) else {
164+ guard let importedNominalType = self . asImportedNominalTypeDecl ( resultType) ,
165+ importedNominalType. swiftNominal. knownTypeKind == nil
166+ else {
174167 printer. print ( " return \( javaUpcall) " )
175168 return
176169 }
@@ -180,7 +173,9 @@ extension JNISwift2JavaGenerator {
180173 let resultName = " _upcallResult "
181174 printer. print (
182175 """
183- let \( resultName) = \( javaUpcall)
176+ guard let \( resultName) = \( javaUpcall) else {
177+ fatalError( " Upcall to \( methodName) unexpectedly returned nil " )
178+ }
184179 let memoryAddress$ = \( resultName) .as(JavaJNISwiftInstance.self)!.memoryAddress()
185180 let pointer = UnsafeMutablePointer<StorageItem>(bitPattern: Int(memoryAddress$))!
186181 return pointer.pointee
@@ -190,38 +185,6 @@ extension JNISwift2JavaGenerator {
190185 printer. print ( javaUpcall)
191186 }
192187 }
193- //
194- // try printer.printBraceBlock(method.swiftDecl.signatureString) { printer in
195- // printer.print(
196- // """
197- // let environment = try! JavaVirtualMachine.shared().environment()
198- // let methodID$: jmethodID!
199- // """
200- // )
201- //
202- // // Passing down Swift parameters to Java basically means
203- // // that we are returning these values to Java,
204- // // we therefore take all the Swift parameters and translate them
205- // // as if they were results.
206- // let upcallValues = try method.functionSignature.parameters.map { parameter in
207- // let result = try self.nativeTranslator.translate(
208- // swiftResult: SwiftResult(
209- // convention: .direct,
210- // type: parameter.type
211- // )
212- // )
213- // return result.conversion.render(&printer, parameter.parameterName!)
214- // }
215- //
216- // let javaResultType = translatedDecl.nativeFunctionSignature.result.javaType
217- // // TODO: Convert arguments to jvalue
218- // printer.print(
219- // """
220- // let javaResult$ = environment.interface.\(javaResultType.jniCallMethodAName)(environment, self.objectHolder.object, methodID$, [\(upcallValues.joined(separator: ", "))])
221- // """
222- // )
223- // }
224-
225188 printer. println ( )
226189 }
227190 }
@@ -297,19 +260,19 @@ extension JNISwift2JavaGenerator {
297260
298261 private func printJavaMacroBindings( _ printer: inout CodePrinter , _ type: ImportedNominalType ) {
299262 // TODO: Nested subclasses here is wrong.
300- let javaTypeName = type. swiftNominal. qualifiedName
301-
302- printer. print (
303- """
304- @JavaClass( " \( javaPackage) . \( javaTypeName) " )
305- open class \( type. generatedJavaClassMacroName) : JavaObject {}
306-
307- extension JavaClass< \( type. generatedJavaClassMacroName) > {
308- @JavaStaticMethod
309- public func wrapMemoryAddressUnsafe(selfPointer: Int64) -> \( type. generatedJavaClassMacroName) !
310- }
311- """
312- )
263+ // let javaTypeName = type.swiftNominal.qualifiedName
264+ //
265+ // printer.print(
266+ // """
267+ // @JavaClass("\(javaPackage).\(javaTypeName)")
268+ // open class \(type.generatedJavaClassMacroName): JavaObject {}
269+ //
270+ // extension JavaClass<\(type.generatedJavaClassMacroName)> {
271+ // @JavaStaticMethod
272+ // public func wrapMemoryAddressUnsafe(selfPointer: Int64) -> \(type.generatedJavaClassMacroName)!
273+ // }
274+ // """
275+ // )
313276 }
314277
315278 private func printProtocolThunks( _ printer: inout CodePrinter , _ type: ImportedNominalType ) throws {
@@ -418,6 +381,8 @@ extension JNISwift2JavaGenerator {
418381 return
419382 }
420383
384+ printSwiftFunctionHelperClasses ( & printer, decl)
385+
421386 printCDecl (
422387 & printer,
423388 translatedDecl
@@ -426,6 +391,61 @@ extension JNISwift2JavaGenerator {
426391 }
427392 }
428393
394+
395+ private func printSwiftFunctionHelperClasses(
396+ _ printer: inout CodePrinter ,
397+ _ decl: ImportedFunc
398+ ) {
399+ let protocolParameters = decl. functionSignature. parameters. compactMap { parameter in
400+ if let concreteType = parameter. type. typeIn (
401+ genericParameters: decl. functionSignature. genericParameters,
402+ genericRequirements: decl. functionSignature. genericRequirements
403+ ) {
404+ return ( parameter, concreteType)
405+ }
406+
407+ switch parameter. type {
408+ case . opaque( let protocolType) ,
409+ . existential( let protocolType) :
410+ return ( parameter, protocolType)
411+
412+ default :
413+ return nil
414+ }
415+ } . map { parameter, protocolType in
416+ // We flatten any composite types
417+ switch protocolType {
418+ case . composite( let protocols) :
419+ return ( parameter, protocols)
420+
421+ default :
422+ return ( parameter, [ protocolType] )
423+ }
424+ }
425+
426+ // For each parameter that is a generic or a protocol,
427+ // we generate a Swift class that conforms to all of those.
428+ for (parameter, protocolTypes) in protocolParameters {
429+ guard let parameterName = parameter. parameterName else {
430+ // TODO: Throw
431+ fatalError ( )
432+ }
433+ let parent = if let parent = decl. parentType {
434+ " \( parent) _ "
435+ } else {
436+ " "
437+ }
438+ let swiftClassName = " _ \( parent) \( decl. name) _ \( parameterName) _Wrapper "
439+ let implementingProtocols = protocolTypes. compactMap {
440+ $0. asNominalType? . javaInterfaceSwiftProtocolWrapperName
441+ } . joined ( separator: " , " )
442+
443+ printer. printBraceBlock ( " final class \( swiftClassName) : \( implementingProtocols) " ) { printer in
444+
445+ }
446+ }
447+ }
448+
429449 private func printFunctionDowncall(
430450 _ printer: inout CodePrinter ,
431451 _ decl: ImportedFunc
@@ -682,8 +702,17 @@ extension JNISwift2JavaGenerator {
682702 }
683703}
684704
685- extension ImportedNominalType {
686- var generatedJavaClassMacroName : String {
687- " Java \( self . swiftNominal. qualifiedName. replacingOccurrences ( of: " . " , with: " _ " ) ) "
705+ extension SwiftNominalType {
706+ private var safeProtocolName : String {
707+ self . nominalTypeDecl. qualifiedName. replacingOccurrences ( of: " . " , with: " _ " )
708+ }
709+
710+ /// The name of the corresponding `@JavaInterface` of this type.
711+ var javaInterfaceName : String {
712+ " Java \( safeProtocolName) "
713+ }
714+
715+ var javaInterfaceSwiftProtocolWrapperName : String {
716+ " SwiftJava \( safeProtocolName) Wrapper "
688717 }
689718}
0 commit comments