@@ -24,7 +24,7 @@ extension JNISwift2JavaGenerator {
2424
2525 let translated : TranslatedFunctionDecl ?
2626 do {
27- let translation = JavaTranslation ( swiftModuleName: swiftModuleName)
27+ let translation = JavaTranslation ( swiftModuleName: swiftModuleName, javaPackage : self . javaPackage )
2828 translated = try translation. translate ( decl)
2929 } catch {
3030 self . logger. debug ( " Failed to translate: ' \( decl. swiftDecl. qualifiedNameForDebug) '; \( error) " )
@@ -37,17 +37,10 @@ extension JNISwift2JavaGenerator {
3737
3838 struct JavaTranslation {
3939 let swiftModuleName : String
40+ let javaPackage : String
4041
4142 func translate( _ decl: ImportedFunc ) throws -> TranslatedFunctionDecl {
42- let nativeTranslation = NativeJavaTranslation ( )
43-
44- // Swift -> Java
45- let translatedFunctionSignature = try translate ( functionSignature: decl. functionSignature)
46- // Java -> Java (native)
47- let nativeFunctionSignature = try nativeTranslation. translate (
48- functionSignature: decl. functionSignature,
49- translatedFunctionSignature: translatedFunctionSignature
50- )
43+ let nativeTranslation = NativeJavaTranslation ( javaPackage: self . javaPackage)
5144
5245 // Types with no parent will be outputted inside a "module" class.
5346 let parentName = decl. parentType? . asNominalType? . nominalTypeDecl. qualifiedName ?? swiftModuleName
@@ -59,27 +52,91 @@ extension JNISwift2JavaGenerator {
5952 case . function, . initializer: decl. name
6053 }
6154
55+ // Swift -> Java
56+ let translatedFunctionSignature = try translate (
57+ functionSignature: decl. functionSignature,
58+ methodName: javaName,
59+ parentName: parentName
60+ )
61+ // Java -> Java (native)
62+ let nativeFunctionSignature = try nativeTranslation. translate (
63+ functionSignature: decl. functionSignature,
64+ translatedFunctionSignature: translatedFunctionSignature,
65+ methodName: javaName,
66+ parentName: parentName
67+ )
68+
69+ // Closures.
70+ var funcTypes : [ TranslatedFunctionType ] = [ ]
71+ for (idx, param) in decl. functionSignature. parameters. enumerated ( ) {
72+ let parameterName = param. parameterName ?? " _ \( idx) "
73+
74+ switch param. type {
75+ case . function( let funcTy) :
76+ let translatedClosure = try translateFunctionType (
77+ name: parameterName,
78+ swiftType: funcTy,
79+ parentName: parentName
80+ )
81+ funcTypes. append ( translatedClosure)
82+ default :
83+ break
84+ }
85+ }
86+
6287 return TranslatedFunctionDecl (
6388 name: javaName,
6489 nativeFunctionName: " $ \( javaName) " ,
6590 parentName: parentName,
91+ functionTypes: funcTypes,
6692 translatedFunctionSignature: translatedFunctionSignature,
6793 nativeFunctionSignature: nativeFunctionSignature
6894 )
6995 }
7096
71- func translate( functionSignature: SwiftFunctionSignature ) throws -> TranslatedFunctionSignature {
97+ /// Translate Swift closure type to Java functional interface.
98+ func translateFunctionType(
99+ name: String ,
100+ swiftType: SwiftFunctionType ,
101+ parentName: String
102+ ) throws -> TranslatedFunctionType {
103+ var translatedParams : [ TranslatedParameter ] = [ ]
104+
105+ for (i, param) in swiftType. parameters. enumerated ( ) {
106+ let paramName = param. parameterName ?? " _ \( i) "
107+ translatedParams. append (
108+ try translateParameter ( swiftType: param. type, parameterName: paramName, methodName: name, parentName: parentName)
109+ )
110+ }
111+
112+ let transltedResult = try translate ( swiftResult: SwiftResult ( convention: . direct, type: swiftType. resultType) )
113+
114+ return TranslatedFunctionType (
115+ name: name,
116+ parameters: translatedParams,
117+ result: transltedResult,
118+ swiftType: swiftType
119+ )
120+ }
121+
122+ func translate(
123+ functionSignature: SwiftFunctionSignature ,
124+ methodName: String ,
125+ parentName: String
126+ ) throws -> TranslatedFunctionSignature {
72127 let parameters = try functionSignature. parameters. enumerated ( ) . map { idx, param in
73128 let parameterName = param. parameterName ?? " arg \( idx) ) "
74- return try translateParameter ( swiftType: param. type, parameterName: parameterName)
129+ return try translateParameter ( swiftType: param. type, parameterName: parameterName, methodName : methodName , parentName : parentName )
75130 }
76131
77132 // 'self'
78133 let selfParameter : TranslatedParameter ?
79134 if case . instance( let swiftSelf) = functionSignature. selfParameter {
80135 selfParameter = try self . translateParameter (
81136 swiftType: swiftSelf. type,
82- parameterName: swiftSelf. parameterName ?? " self "
137+ parameterName: swiftSelf. parameterName ?? " self " ,
138+ methodName: methodName,
139+ parentName: parentName
83140 )
84141 } else {
85142 selfParameter = nil
@@ -92,7 +149,12 @@ extension JNISwift2JavaGenerator {
92149 )
93150 }
94151
95- func translateParameter( swiftType: SwiftType , parameterName: String ) throws -> TranslatedParameter {
152+ func translateParameter(
153+ swiftType: SwiftType ,
154+ parameterName: String ,
155+ methodName: String ,
156+ parentName: String
157+ ) throws -> TranslatedParameter {
96158 switch swiftType {
97159 case . nominal( let nominalType) :
98160 if let knownType = nominalType. nominalTypeDecl. knownTypeKind {
@@ -121,7 +183,16 @@ extension JNISwift2JavaGenerator {
121183 conversion: . placeholder
122184 )
123185
124- case . metatype, . optional, . tuple, . function, . existential, . opaque:
186+ case . function:
187+ return TranslatedParameter (
188+ parameter: JavaParameter (
189+ name: parameterName,
190+ type: . class( package : javaPackage, name: " \( parentName) . \( methodName) . \( parameterName) " )
191+ ) ,
192+ conversion: . placeholder
193+ )
194+
195+ case . metatype, . optional, . tuple, . existential, . opaque:
125196 throw JavaTranslationError . unsupportedSwiftType ( swiftType)
126197 }
127198 }
@@ -168,6 +239,9 @@ extension JNISwift2JavaGenerator {
168239 /// The name of the Java parent scope this function is declared in
169240 let parentName : String
170241
242+ /// Functional interfaces required for the Java method.
243+ let functionTypes : [ TranslatedFunctionType ]
244+
171245 /// Function signature of the Java function the user will call
172246 let translatedFunctionSignature : TranslatedFunctionSignature
173247
@@ -220,6 +294,16 @@ extension JNISwift2JavaGenerator {
220294 let conversion : JavaNativeConversionStep
221295 }
222296
297+ /// Represent a Swift closure type in the user facing Java API.
298+ ///
299+ /// Closures are translated to named functional interfaces in Java.
300+ struct TranslatedFunctionType {
301+ var name : String
302+ var parameters : [ TranslatedParameter ]
303+ var result : TranslatedResult
304+ var swiftType : SwiftFunctionType
305+ }
306+
223307 /// Describes how to convert values between Java types and the native Java function
224308 enum JavaNativeConversionStep {
225309 /// The value being converted
0 commit comments