@@ -182,8 +182,7 @@ extension FFMSwift2JavaGenerator {
182182 /// }
183183 /// ```
184184 ///
185- /// If a `functionBody` is provided the `Function` becomes a `final static class`,
186- /// with the specified implementation as the implementation of the `apply` method.
185+ /// If a `functionBody` is provided, a `Function$Impl` class will be emitted as well.
187186 func printFunctionPointerParameterDescriptorClass(
188187 _ printer: inout CodePrinter ,
189188 _ name: String ,
@@ -217,27 +216,28 @@ extension FFMSwift2JavaGenerator {
217216 private static class \( name)
218217 """
219218 ) { printer in
219+ printer. print (
220+ """
221+ @FunctionalInterface
222+ public interface Function {
223+ \( cResultType. javaType) apply( \( paramDecls. joined ( separator: " , " ) ) );
224+ }
225+ """
226+ )
227+
220228 if let impl {
221229 printer. print (
222230 """
223- public final static class Function {
231+ public final static class Function$Impl implements Function {
224232 \( impl. members. joinedJavaStatements ( indent: 2 ) )
225- \( cResultType. javaType) apply( \( paramDecls. joined ( separator: " , " ) ) ) {
233+ public \( cResultType. javaType) apply( \( paramDecls. joined ( separator: " , " ) ) ) {
226234 \( impl. body)
227235 }
228236 }
229237 """
230238 )
231- } else {
232- printer. print (
233- """
234- @FunctionalInterface
235- public interface Function {
236- \( cResultType. javaType) apply( \( paramDecls. joined ( separator: " , " ) ) );
237- }
238- """
239- )
240- }
239+ }
240+
241241 printFunctionDescriptorDefinition ( & printer, cResultType, cParams)
242242 printer. print (
243243 """
@@ -456,19 +456,20 @@ extension FFMSwift2JavaGenerator {
456456 downCallArguments. append ( varName)
457457 }
458458
459+ let thunkName = thunkNameRegistry. functionThunkName ( decl: decl)
460+
459461 if let outCallback = translatedSignature. result. outCallback {
460462 let funcName = outCallback. name
461463 assert ( funcName. first == " $ " , " OutCallback names must start with $ " )
462464 let varName = funcName. dropFirst ( )
463465 downCallArguments. append (
464466 """
465- swiftjava_SwiftModule_returnArray . \( outCallback. name) .toUpcallStub( \( varName) , arena$)
467+ \( thunkName ) . \( outCallback. name) .toUpcallStub( \( varName) , arena$)
466468 """
467469 )
468470 }
469471
470472 //=== Part 3: Downcall.
471- let thunkName = thunkNameRegistry. functionThunkName ( decl: decl)
472473 let downCall = " \( thunkName) .call( \( downCallArguments. joined ( separator: " , " ) ) ) "
473474
474475 //=== Part 4: Convert the return value.
@@ -527,7 +528,9 @@ extension FFMSwift2JavaGenerator.JavaConversionStep {
527528 /// Whether the conversion uses SwiftArena.
528529 var requiresSwiftArena : Bool {
529530 switch self {
530- case . placeholder, . placeholderForDowncall, . explodedName, . constant, . readMemorySegment:
531+ case . placeholder, . placeholderForDowncall, . placeholderForSwiftThunkName:
532+ return false
533+ case . explodedName, . constant, . readMemorySegment, . javaNew:
531534 return false
532535 case . constructSwiftValue, . wrapMemoryAddressUnsafe:
533536 return true
@@ -536,6 +539,8 @@ extension FFMSwift2JavaGenerator.JavaConversionStep {
536539
537540 case . initializeResultWithUpcall( let steps, let result) :
538541 return steps. contains { $0. requiresSwiftArena } || result. requiresSwiftArena
542+ case . introduceVariable( _, let value) :
543+ return value. requiresSwiftArena
539544
540545 case . call( let inner, let base, _, _) :
541546 return inner. requiresSwiftArena || ( base? . requiresSwiftArena == true )
@@ -547,22 +552,26 @@ extension FFMSwift2JavaGenerator.JavaConversionStep {
547552 . swiftValueSelfSegment( let inner) :
548553 return inner. requiresSwiftArena
549554
550- case . commaSeparated( let list) :
555+ case . commaSeparated( let list, _ ) :
551556 return list. contains ( where: { $0. requiresSwiftArena } )
552557 }
553558 }
554559
555560 /// Whether the conversion uses temporary Arena.
556561 var requiresTemporaryArena : Bool {
557562 switch self {
558- case . placeholder, . placeholderForDowncall, . explodedName, . constant:
563+ case . placeholder, . placeholderForDowncall, . placeholderForSwiftThunkName:
564+ return false
565+ case . explodedName, . constant, . javaNew:
559566 return false
560567 case . temporaryArena:
561568 return true
562569 case . readMemorySegment:
563570 return true
564571 case . initializeResultWithUpcall:
565572 return true
573+ case . introduceVariable( _, let value) :
574+ return value. requiresTemporaryArena
566575 case . cast( let inner, _) ,
567576 . construct( let inner, _) ,
568577 . constructSwiftValue( let inner, _) ,
@@ -575,7 +584,7 @@ extension FFMSwift2JavaGenerator.JavaConversionStep {
575584 return withArena || inner. requiresTemporaryArena || args. contains ( where: { $0. requiresTemporaryArena } )
576585 case . property( let inner, _) :
577586 return inner. requiresTemporaryArena
578- case . commaSeparated( let list) :
587+ case . commaSeparated( let list, _ ) :
579588 return list. contains ( where: { $0. requiresTemporaryArena } )
580589 }
581590 }
@@ -594,17 +603,28 @@ extension FFMSwift2JavaGenerator.JavaConversionStep {
594603 } else {
595604 return " /*placeholderForDowncall undefined!*/"
596605 }
606+ case . placeholderForSwiftThunkName:
607+ if let placeholderForDowncall {
608+ let downcall = " \( placeholderForDowncall) "
609+ return String ( downcall [ ..< ( downcall. firstIndex ( of: " . " ) ?? downcall. endIndex) ] ) // . separates thunk name from the `.call`
610+ } else {
611+ return " /*placeholderForDowncall undefined!*/"
612+ }
613+
614+ case . temporaryArena:
615+ return " arena$ "
597616
598617 case . explodedName( let component) :
599618 return " \( placeholder) _ \( component) "
600619
601620 case . swiftValueSelfSegment:
602621 return " \( placeholder) .$memorySegment() "
603622
604- case . temporaryArena :
605- return " arena$ "
623+ case . javaNew ( let value ) :
624+ return " new \( value . render ( & printer , placeholder , placeholderForDowncall : placeholderForDowncall ) ) "
606625
607626 case . initializeResultWithUpcall( let steps, _) :
627+ // TODO: could we use the printing to introduce the upcall handle instead?
608628 return steps. map { step in
609629 var printer = CodePrinter ( )
610630 var out = " "
@@ -626,33 +646,39 @@ extension FFMSwift2JavaGenerator.JavaConversionStep {
626646
627647 // TODO: deduplicate with 'method'
628648 case . method( let inner, let methodName, let arguments, let withArena) :
629- let inner = inner. render ( & printer, placeholder)
630- let args = arguments. map { $0. render ( & printer, placeholder) }
649+ let inner = inner. render ( & printer, placeholder, placeholderForDowncall : placeholderForDowncall )
650+ let args = arguments. map { $0. render ( & printer, placeholder, placeholderForDowncall : placeholderForDowncall ) }
631651 let argsStr = ( args + ( withArena ? [ " arena$ " ] : [ ] ) ) . joined ( separator: " , " )
632652 return " \( inner) . \( methodName) ( \( argsStr) ) "
633653
634654 case . property( let inner, let propertyName) :
635- let inner = inner. render ( & printer, placeholder)
655+ let inner = inner. render ( & printer, placeholder, placeholderForDowncall : placeholderForDowncall )
636656 return " \( inner) . \( propertyName) "
637657
638658 case . constructSwiftValue( let inner, let javaType) :
639- let inner = inner. render ( & printer, placeholder)
659+ let inner = inner. render ( & printer, placeholder, placeholderForDowncall : placeholderForDowncall )
640660 return " new \( javaType. className!) ( \( inner) , swiftArena$) "
641661
642662 case . wrapMemoryAddressUnsafe( let inner, let javaType) :
643- let inner = inner. render ( & printer, placeholder)
663+ let inner = inner. render ( & printer, placeholder, placeholderForDowncall : placeholderForDowncall )
644664 return " \( javaType. className!) .wrapMemoryAddressUnsafe( \( inner) , swiftArena$) "
645665
646666 case . construct( let inner, let javaType) :
647- let inner = inner. render ( & printer, placeholder)
667+ let inner = inner. render ( & printer, placeholder, placeholderForDowncall : placeholderForDowncall )
648668 return " new \( javaType) ( \( inner) ) "
669+
670+ case . introduceVariable( let name, let value) :
671+ let value = value. render ( & printer, placeholder, placeholderForDowncall: placeholderForDowncall)
672+ return " var \( name) = \( value) ; "
649673
650674 case . cast( let inner, let javaType) :
651- let inner = inner. render ( & printer, placeholder)
675+ let inner = inner. render ( & printer, placeholder, placeholderForDowncall : placeholderForDowncall )
652676 return " ( \( javaType) ) \( inner) "
653677
654- case . commaSeparated( let list) :
655- return list. map ( { $0. render ( & printer, placeholder) } ) . joined ( separator: " , " )
678+ case . commaSeparated( let list, let separator) :
679+ return list. map ( {
680+ $0. render ( & printer, placeholder, placeholderForDowncall: placeholderForDowncall)
681+ } ) . joined ( separator: separator)
656682
657683 case . constant( let value) :
658684 return value
0 commit comments