@@ -24,7 +24,7 @@ extension JNISwift2JavaGenerator {
24
24
25
25
let translated : TranslatedFunctionDecl ?
26
26
do {
27
- let translation = JavaTranslation ( swiftModuleName: swiftModuleName)
27
+ let translation = JavaTranslation ( swiftModuleName: swiftModuleName, javaPackage : self . javaPackage )
28
28
translated = try translation. translate ( decl)
29
29
} catch {
30
30
self . logger. debug ( " Failed to translate: ' \( decl. swiftDecl. qualifiedNameForDebug) '; \( error) " )
@@ -37,17 +37,10 @@ extension JNISwift2JavaGenerator {
37
37
38
38
struct JavaTranslation {
39
39
let swiftModuleName : String
40
+ let javaPackage : String
40
41
41
42
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)
51
44
52
45
// Types with no parent will be outputted inside a "module" class.
53
46
let parentName = decl. parentType? . asNominalType? . nominalTypeDecl. qualifiedName ?? swiftModuleName
@@ -59,26 +52,90 @@ extension JNISwift2JavaGenerator {
59
52
case . function, . initializer: decl. name
60
53
}
61
54
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
+
62
87
return TranslatedFunctionDecl (
63
88
name: javaName,
64
89
parentName: parentName,
90
+ functionTypes: funcTypes,
65
91
translatedFunctionSignature: translatedFunctionSignature,
66
92
nativeFunctionSignature: nativeFunctionSignature
67
93
)
68
94
}
69
95
70
- func translate( functionSignature: SwiftFunctionSignature ) throws -> TranslatedFunctionSignature {
96
+ /// Translate Swift closure type to Java functional interface.
97
+ func translateFunctionType(
98
+ name: String ,
99
+ swiftType: SwiftFunctionType ,
100
+ parentName: String
101
+ ) throws -> TranslatedFunctionType {
102
+ var translatedParams : [ TranslatedParameter ] = [ ]
103
+
104
+ for (i, param) in swiftType. parameters. enumerated ( ) {
105
+ let paramName = param. parameterName ?? " _ \( i) "
106
+ translatedParams. append (
107
+ try translateParameter ( swiftType: param. type, parameterName: paramName, methodName: name, parentName: parentName)
108
+ )
109
+ }
110
+
111
+ let transltedResult = try translate ( swiftResult: SwiftResult ( convention: . direct, type: swiftType. resultType) )
112
+
113
+ return TranslatedFunctionType (
114
+ name: name,
115
+ parameters: translatedParams,
116
+ result: transltedResult,
117
+ swiftType: swiftType
118
+ )
119
+ }
120
+
121
+ func translate(
122
+ functionSignature: SwiftFunctionSignature ,
123
+ methodName: String ,
124
+ parentName: String
125
+ ) throws -> TranslatedFunctionSignature {
71
126
let parameters = try functionSignature. parameters. enumerated ( ) . map { idx, param in
72
127
let parameterName = param. parameterName ?? " arg \( idx) ) "
73
- return try translateParameter ( swiftType: param. type, parameterName: parameterName)
128
+ return try translateParameter ( swiftType: param. type, parameterName: parameterName, methodName : methodName , parentName : parentName )
74
129
}
75
130
76
131
// 'self'
77
132
let selfParameter : TranslatedParameter ?
78
133
if case . instance( let swiftSelf) = functionSignature. selfParameter {
79
134
selfParameter = try self . translateParameter (
80
135
swiftType: swiftSelf. type,
81
- parameterName: swiftSelf. parameterName ?? " self "
136
+ parameterName: swiftSelf. parameterName ?? " self " ,
137
+ methodName: methodName,
138
+ parentName: parentName
82
139
)
83
140
} else {
84
141
selfParameter = nil
@@ -91,7 +148,12 @@ extension JNISwift2JavaGenerator {
91
148
)
92
149
}
93
150
94
- func translateParameter( swiftType: SwiftType , parameterName: String ) throws -> TranslatedParameter {
151
+ func translateParameter(
152
+ swiftType: SwiftType ,
153
+ parameterName: String ,
154
+ methodName: String ,
155
+ parentName: String
156
+ ) throws -> TranslatedParameter {
95
157
switch swiftType {
96
158
case . nominal( let nominalType) :
97
159
if let knownType = nominalType. nominalTypeDecl. knownTypeKind {
@@ -120,7 +182,16 @@ extension JNISwift2JavaGenerator {
120
182
conversion: . placeholder
121
183
)
122
184
123
- case . metatype, . optional, . tuple, . function, . existential, . opaque:
185
+ case . function:
186
+ return TranslatedParameter (
187
+ parameter: JavaParameter (
188
+ name: parameterName,
189
+ type: . class( package : javaPackage, name: " \( parentName) . \( methodName) . \( parameterName) " )
190
+ ) ,
191
+ conversion: . placeholder
192
+ )
193
+
194
+ case . metatype, . optional, . tuple, . existential, . opaque:
124
195
throw JavaTranslationError . unsupportedSwiftType ( swiftType)
125
196
}
126
197
}
@@ -164,6 +235,9 @@ extension JNISwift2JavaGenerator {
164
235
/// The name of the Java parent scope this function is declared in
165
236
let parentName : String
166
237
238
+ /// Functional interfaces required for the Java method.
239
+ let functionTypes : [ TranslatedFunctionType ]
240
+
167
241
/// Function signature of the Java function the user will call
168
242
let translatedFunctionSignature : TranslatedFunctionSignature
169
243
@@ -216,6 +290,16 @@ extension JNISwift2JavaGenerator {
216
290
let conversion : JavaNativeConversionStep
217
291
}
218
292
293
+ /// Represent a Swift closure type in the user facing Java API.
294
+ ///
295
+ /// Closures are translated to named functional interfaces in Java.
296
+ struct TranslatedFunctionType {
297
+ var name : String
298
+ var parameters : [ TranslatedParameter ]
299
+ var result : TranslatedResult
300
+ var swiftType : SwiftFunctionType
301
+ }
302
+
219
303
/// Describes how to convert values between Java types and the native Java function
220
304
enum JavaNativeConversionStep {
221
305
/// The value being converted
0 commit comments