@@ -259,8 +259,8 @@ extension JNISwift2JavaGenerator {
259259 case . short: ( " Optional<Short> " , " (short) 0 " )
260260 case . int: ( " OptionalInt " , " 0 " )
261261 case . long: ( " OptionalLong " , " 0L " )
262- case . float: ( " Optional<Float> " , " 0 " )
263- case . double: ( " OptionalDouble " , " 0 " )
262+ case . float: ( " Optional<Float> " , " 0f " )
263+ case . double: ( " OptionalDouble " , " 0.0 " )
264264 case . javaLangString: ( " Optional<String> " , #""""# )
265265 default :
266266 throw JavaTranslationError . unsupportedSwiftType ( swiftType)
@@ -321,6 +321,7 @@ extension JNISwift2JavaGenerator {
321321
322322 return TranslatedResult (
323323 javaType: javaType,
324+ outParameters: [ ] ,
324325 conversion: . placeholder
325326 )
326327 }
@@ -334,11 +335,12 @@ extension JNISwift2JavaGenerator {
334335 let javaType = JavaType . class ( package : nil , name: nominalType. nominalTypeDecl. name)
335336 return TranslatedResult (
336337 javaType: javaType,
338+ outParameters: [ ] ,
337339 conversion: . constructSwiftValue( . placeholder, javaType)
338340 )
339341
340342 case . tuple( [ ] ) :
341- return TranslatedResult ( javaType: . void, conversion: . placeholder)
343+ return TranslatedResult ( javaType: . void, outParameters : [ ] , conversion: . placeholder)
342344
343345 case . optional( let wrapped) :
344346 return try translateOptionalResult ( wrappedType: wrapped)
@@ -379,6 +381,7 @@ extension JNISwift2JavaGenerator {
379381 if let nextIntergralTypeWithSpaceForByte = javaType. nextIntergralTypeWithSpaceForByte {
380382 return TranslatedResult (
381383 javaType: . class( package : nil , name: returnType) ,
384+ outParameters: [ ] ,
382385 conversion: . combinedValueToOptional(
383386 . placeholder,
384387 nextIntergralTypeWithSpaceForByte. java,
@@ -388,8 +391,28 @@ extension JNISwift2JavaGenerator {
388391 )
389392 )
390393 } else {
391- // Otherwise, we are forced to use an array.
392- fatalError ( )
394+ // Otherwise, we return the result as normal, but
395+ // use an indirect return for the discriminator.
396+ return TranslatedResult (
397+ javaType: . class( package : nil , name: returnType) ,
398+ outParameters: [
399+ OutParameter ( name: " result_discriminator$ " , type: . array( . byte) , allocation: . newArray( . byte, size: 1 ) )
400+ ] ,
401+ conversion: . aggregate(
402+ name: " result$ " ,
403+ type: javaType,
404+ [
405+ . ternary(
406+ . equals(
407+ . subscriptOf( . constant( " result_discriminator$ " ) , arguments: [ . constant( " 0 " ) ] ) ,
408+ . constant( " 1 " )
409+ ) ,
410+ thenExp: . method( . constant( staticCallee) , function: " of " , arguments: [ . constant( " result$ " ) ] ) ,
411+ elseExp: . method( . constant( staticCallee) , function: " empty " )
412+ )
413+ ]
414+ )
415+ )
393416 }
394417 }
395418
@@ -467,10 +490,33 @@ extension JNISwift2JavaGenerator {
467490 struct TranslatedResult {
468491 let javaType : JavaType
469492
493+ let outParameters : [ OutParameter ]
494+
470495 /// Represents how to convert the Java native result into a user-facing result.
471496 let conversion : JavaNativeConversionStep
472497 }
473498
499+ struct OutParameter {
500+ enum Allocation {
501+ case newArray( JavaType , size: Int )
502+
503+ func render( ) -> String {
504+ switch self {
505+ case . newArray( let javaType, let size) :
506+ " new \( javaType) [ \( size) ] "
507+ }
508+ }
509+ }
510+
511+ let name : String
512+ let type : JavaType
513+ let allocation : Allocation
514+
515+ var javaParameter : JavaParameter {
516+ JavaParameter ( name: self . name, type: self . type)
517+ }
518+ }
519+
474520 /// Represent a Swift closure type in the user facing Java API.
475521 ///
476522 /// Closures are translated to named functional interfaces in Java.
@@ -500,12 +546,21 @@ extension JNISwift2JavaGenerator {
500546 /// Call `new \(Type)(\(placeholder), swiftArena$)`
501547 indirect case constructSwiftValue( JavaNativeConversionStep , JavaType )
502548
503- indirect case method( JavaNativeConversionStep , function: String , arguments: [ JavaNativeConversionStep ] )
549+ indirect case method( JavaNativeConversionStep , function: String , arguments: [ JavaNativeConversionStep ] = [ ] )
504550
505551 case isOptionalPresent
506552
507553 indirect case combinedValueToOptional( JavaNativeConversionStep , JavaType , valueType: JavaType , valueSizeInBytes: Int , optionalType: String )
508554
555+ indirect case ternary( JavaNativeConversionStep , thenExp: JavaNativeConversionStep , elseExp: JavaNativeConversionStep )
556+
557+ indirect case equals( JavaNativeConversionStep , JavaNativeConversionStep )
558+
559+ indirect case subscriptOf( JavaNativeConversionStep , arguments: [ JavaNativeConversionStep ] )
560+
561+ /// Perform multiple conversions using the same input.
562+ case aggregate( name: String , type: JavaType , [ JavaNativeConversionStep ] )
563+
509564 /// Returns the conversion string applied to the placeholder.
510565 func render( _ printer: inout CodePrinter , _ placeholder: String ) -> String {
511566 // NOTE: 'printer' is used if the conversion wants to cause side-effects.
@@ -555,6 +610,30 @@ extension JNISwift2JavaGenerator {
555610 }
556611
557612 return " discriminator$ == 1 ? \( optionalType) .of(value$) : \( optionalType) .empty() "
613+
614+ case . ternary( let cond, let thenExp, let elseExp) :
615+ let cond = cond. render ( & printer, placeholder)
616+ let thenExp = thenExp. render ( & printer, placeholder)
617+ let elseExp = elseExp. render ( & printer, placeholder)
618+ return " ( \( cond) ) ? \( thenExp) : \( elseExp) "
619+
620+ case . equals( let lhs, let rhs) :
621+ let lhs = lhs. render ( & printer, placeholder)
622+ let rhs = rhs. render ( & printer, placeholder)
623+ return " \( lhs) == \( rhs) "
624+
625+ case . subscriptOf( let inner, let arguments) :
626+ let inner = inner. render ( & printer, placeholder)
627+ let arguments = arguments. map { $0. render ( & printer, placeholder) }
628+ return " \( inner) [ \( arguments. joined ( separator: " , " ) ) ] "
629+
630+ case . aggregate( let name, let type, let steps) :
631+ precondition ( !steps. isEmpty, " Aggregate must contain steps " )
632+ printer. print ( " \( type) \( name) = \( placeholder) ; " )
633+ let steps = steps. map {
634+ $0. render ( & printer, name)
635+ }
636+ return steps. last!
558637 }
559638 }
560639
@@ -578,6 +657,18 @@ extension JNISwift2JavaGenerator {
578657
579658 case . combinedValueToOptional( let inner, _, _, _, _) :
580659 return inner. requiresSwiftArena
660+
661+ case . ternary( let cond, let thenExp, let elseExp) :
662+ return cond. requiresSwiftArena || thenExp. requiresSwiftArena || elseExp. requiresSwiftArena
663+
664+ case . equals( let lhs, let rhs) :
665+ return lhs. requiresSwiftArena || rhs. requiresSwiftArena
666+
667+ case . subscriptOf( let inner, _) :
668+ return inner. requiresSwiftArena
669+
670+ case . aggregate( _, _, let steps) :
671+ return steps. contains ( where: \. requiresSwiftArena)
581672 }
582673 }
583674 }
0 commit comments