@@ -117,7 +117,7 @@ extension JNISwift2JavaGenerator {
117117 printer. println ( )
118118
119119 for initializer in decl. initializers {
120- printInitializerBindings ( & printer, initializer, type : decl )
120+ printFunctionBinding ( & printer, initializer)
121121 printer. println ( )
122122 }
123123
@@ -176,75 +176,82 @@ extension JNISwift2JavaGenerator {
176176 }
177177
178178 private func printFunctionBinding( _ printer: inout CodePrinter , _ decl: ImportedFunc ) {
179- guard let _ = translatedDecl ( for: decl) else {
179+ guard let translatedDecl = translatedDecl ( for: decl) else {
180180 // Failed to translate. Skip.
181181 return
182182 }
183183
184+ var modifiers = [ " public " ]
184185 if decl. isStatic || decl. isInitializer || !decl. hasParent {
185- printStaticFunctionBinding ( & printer, decl)
186- } else {
187- printMemberMethodBindings ( & printer, decl)
186+ modifiers. append ( " static " )
188187 }
189- }
190188
191- private func printStaticFunctionBinding( _ printer: inout CodePrinter , _ decl: ImportedFunc ) {
192- printDeclDocumentation ( & printer, decl)
193- printer. print (
194- " public static native \( renderFunctionSignature ( decl) ) ; "
195- )
196- }
189+ let translatedSignature = translatedDecl. translatedFunctionSignature
190+ let resultType = translatedSignature. resultType. javaType
191+ var parameters = translatedDecl. translatedFunctionSignature. parameters. map ( \. parameter. asParameter)
192+ if translatedSignature. requiresSwiftArena {
193+ parameters. append ( " SwiftArena swiftArena$ " )
194+ }
195+ let throwsClause = decl. isThrowing ? " throws Exception " : " "
197196
198- /// Renders Java bindings for member methods
199- ///
200- /// Member methods are generated as a function that extracts the `selfPointer`
201- /// and passes it down to another native function along with the arguments
202- /// to call the Swift implementation.
203- private func printMemberMethodBindings( _ printer: inout CodePrinter , _ decl: ImportedFunc ) {
204- let translatedDecl = translatedDecl ( for: decl) ! // We will only call this method if we can translate the decl.
197+ let modifiersStr = modifiers. joined ( separator: " " )
198+ let parametersStr = parameters. joined ( separator: " , " )
205199
206200 printDeclDocumentation ( & printer, decl)
207- printer. printBraceBlock ( " public \( renderFunctionSignature ( decl ) ) " ) { printer in
208- var arguments = translatedDecl. translatedFunctionSignature . parameters . map ( \ . name )
209-
210- let selfVarName = " self$ "
211- arguments . append ( selfVarName )
201+ printer. printBraceBlock (
202+ " \( modifiersStr ) \( resultType ) \( translatedDecl. name ) ( \( parametersStr ) ) \( throwsClause ) "
203+ ) { printer in
204+ printDowncall ( & printer , decl )
205+ }
212206
213- let returnKeyword = translatedDecl. translatedFunctionSignature. resultType. isVoid ? " " : " return "
207+ printNativeFunction ( & printer, decl)
208+ }
214209
215- printer. print (
216- """
217- long \( selfVarName) = this.$memoryAddress();
218- \( returnKeyword) \( translatedDecl. parentName) .$ \( translatedDecl. name) ( \( arguments. joined ( separator: " , " ) ) );
219- """
220- )
210+ private func printNativeFunction( _ printer: inout CodePrinter , _ decl: ImportedFunc ) {
211+ let translatedDecl = translatedDecl ( for: decl) ! // Will always call with valid decl
212+ let nativeSignature = translatedDecl. nativeFunctionSignature
213+ let resultType = nativeSignature. result. javaType
214+ var parameters = nativeSignature. parameters
215+ if let selfParameter = nativeSignature. selfParameter {
216+ parameters. append ( selfParameter)
221217 }
218+ let renderedParameters = parameters. map { " \( $0. javaParameter. type) \( $0. javaParameter. name) " } . joined ( separator: " , " )
222219
223- let returnType = translatedDecl. translatedFunctionSignature. resultType
224- var parameters = translatedDecl. translatedFunctionSignature. parameters. map ( \. asParameter)
225- parameters. append ( " long selfPointer " )
226- printer. print ( " private static native \( returnType) $ \( translatedDecl. name) ( \( parameters. joined ( separator: " , " ) ) ); " )
220+ printer. print ( " private static native \( resultType) \( translatedDecl. nativeFunctionName) ( \( renderedParameters) ); " )
227221 }
228222
229- private func printInitializerBindings( _ printer: inout CodePrinter , _ decl: ImportedFunc , type: ImportedNominalType ) {
230- guard let translatedDecl = translatedDecl ( for: decl) else {
231- // Failed to translate. Skip.
232- return
223+ private func printDowncall(
224+ _ printer: inout CodePrinter ,
225+ _ decl: ImportedFunc
226+ ) {
227+ let translatedDecl = translatedDecl ( for: decl) ! // We will only call this method if we can translate the decl.
228+ let translatedFunctionSignature = translatedDecl. translatedFunctionSignature
229+
230+ // Regular parameters.
231+ var arguments = [ String] ( )
232+ for parameter in translatedFunctionSignature. parameters {
233+ let lowered = parameter. conversion. render ( & printer, parameter. parameter. name)
234+ arguments. append ( lowered)
233235 }
234236
235- printDeclDocumentation ( & printer, decl)
236- printer. printBraceBlock ( " public static \( renderFunctionSignature ( decl) ) " ) { printer in
237- let initArguments = translatedDecl. translatedFunctionSignature. parameters. map ( \. name)
238- printer. print (
239- """
240- long self$ = \( type. qualifiedName) .allocatingInit( \( initArguments. joined ( separator: " , " ) ) );
241- return new \( type. qualifiedName) (self$, swiftArena$);
242- """
243- )
237+ // 'self' parameter.
238+ if let selfParameter = translatedFunctionSignature. selfParameter {
239+ let lowered = selfParameter. conversion. render ( & printer, " this " )
240+ arguments. append ( lowered)
244241 }
245242
246- let parameters = translatedDecl. translatedFunctionSignature. parameters. map ( \. asParameter)
247- printer. print ( " private static native long allocatingInit( \( parameters. joined ( separator: " , " ) ) ); " )
243+ //=== Part 3: Downcall.
244+ // TODO: If we always generate a native method and a "public" method, we can actually choose our own thunk names
245+ // using the registry?
246+ let downcall = " \( translatedDecl. parentName) . \( translatedDecl. nativeFunctionName) ( \( arguments. joined ( separator: " , " ) ) ) "
247+
248+ //=== Part 4: Convert the return value.
249+ if translatedFunctionSignature. resultType. javaType. isVoid {
250+ printer. print ( " \( downcall) ; " )
251+ } else {
252+ let result = translatedFunctionSignature. resultType. conversion. render ( & printer, downcall)
253+ printer. print ( " return \( result) ; " )
254+ }
248255 }
249256
250257 private func printDeclDocumentation( _ printer: inout CodePrinter , _ decl: ImportedFunc ) {
@@ -288,24 +295,4 @@ extension JNISwift2JavaGenerator {
288295 )
289296 }
290297 }
291-
292- /// Renders a Java function signature
293- ///
294- /// `func method(x: Int, y: Int) -> Int` becomes
295- /// `long method(long x, long y)`
296- private func renderFunctionSignature( _ decl: ImportedFunc ) -> String {
297- guard let translatedDecl = translatedDecl ( for: decl) else {
298- fatalError ( " Unable to render function signature for a function that cannot be translated: \( decl) " )
299- }
300- let resultType = translatedDecl. translatedFunctionSignature. resultType
301- var parameters = translatedDecl. translatedFunctionSignature. parameters. map ( \. asParameter)
302-
303- if decl. isInitializer {
304- parameters. append ( " SwiftArena swiftArena$ " )
305- }
306-
307- let throwsClause = decl. isThrowing ? " throws Exception " : " "
308-
309- return " \( resultType) \( translatedDecl. name) ( \( parameters. joined ( separator: " , " ) ) ) \( throwsClause) "
310- }
311298}
0 commit comments