[WIP] Swift export: introduce & use ConversionResult in bridges
diff --git a/native/swift/sir-providers/src/org/jetbrains/kotlin/sir/providers/impl/BridgeProvider/TypeBridging.kt b/native/swift/sir-providers/src/org/jetbrains/kotlin/sir/providers/impl/BridgeProvider/TypeBridging.kt
index 9c60cd0..03ad8afe4 100644
--- a/native/swift/sir-providers/src/org/jetbrains/kotlin/sir/providers/impl/BridgeProvider/TypeBridging.kt
+++ b/native/swift/sir-providers/src/org/jetbrains/kotlin/sir/providers/impl/BridgeProvider/TypeBridging.kt
@@ -160,15 +160,47 @@
  * Generate value conversions from Swift to Kotlin.
  */
 internal interface SwiftToKotlinValueConversion {
-    fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String): String = valueExpression
+    fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String): ConversionResult = valueExpression.direct()
 
     fun swiftToKotlinComponent(typeNamer: SirTypeNamer, valueExpression: String, index: Int): String =
-        if (index == 1) swiftToKotlin(typeNamer, valueExpression)
-        else error("Transformation to indexed components is supported only for Swift structures")
+        error("Transformation to indexed components is supported only for Swift structures")
 
     fun swiftToKotlinComponentConnector(): String = ""
 }
 
+internal sealed class ConversionResult {
+    class Direct(val expression: String) : ConversionResult() {
+        override fun toString(): String = expression
+    }
+
+    class ExternalRcRef(val argument: ConversionResult) : ConversionResult() {
+        override fun toString(): String = "$argument.__externalRCRef()"
+    }
+
+    class BinaryOp(val left: ConversionResult, val operator: String, val right: ConversionResult) : ConversionResult() {
+        override fun toString(): String = "$left$operator$right"
+
+        fun replace(operator: String = this.operator, transform: (ConversionResult) -> ConversionResult) =
+            BinaryOp(transform(left), operator, transform(right))
+    }
+
+    object Unit : ConversionResult() {
+        override fun toString(): String = "Unit"
+    }
+
+    object Null : ConversionResult() {
+        override fun toString(): String = "null"
+    }
+}
+
+private fun String.direct() = ConversionResult.Direct(this)
+
+internal fun String.parameterX(index: Int) = ConversionResult.Direct("${this}_$index")
+
+internal fun String.property(name: String) = ConversionResult.Direct("$this.$name")
+
+private fun String.externalRcRef() = ConversionResult.ExternalRcRef(direct())
+
 /**
  * Generate value conversions from Kotlin to Swift.
  */
@@ -182,13 +214,13 @@
 internal interface ValueConversion : SwiftToKotlinValueConversion, KotlinToSwiftValueConversion
 
 internal object IdentityValueConversion : ValueConversion {
-    override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String) = valueExpression
+    override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String): ConversionResult = valueExpression.direct()
     override fun kotlinToSwift(typeNamer: SirTypeNamer, valueExpression: String) = valueExpression
 }
 
-private fun String.mapSwift(temporalName: String = "it", transform: (String) -> String): String {
+private fun String.mapSwift(temporalName: ConversionResult = "it".direct(), transform: (ConversionResult) -> ConversionResult): ConversionResult {
     val adapter = transform(temporalName).takeIf { it != temporalName }
-    return this + (adapter?.let { ".map { $temporalName in $it }" } ?: "")
+    return (this + (adapter?.let { ".map { $temporalName in $it }" } ?: "")).direct()
 }
 
 internal sealed interface AnyBridge {
@@ -281,7 +313,7 @@
 
     object AsVoid : WithSingleType(SirNominalType(SirSwiftModule.void), KotlinType.Unit, CType.Void) {
         override val inKotlinSources = object : ValueConversion {
-            override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String): String = "Unit"
+            override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String) = ConversionResult.Unit
 
             override fun kotlinToSwift(typeNamer: SirTypeNamer, valueExpression: String): String = valueExpression
         }
@@ -295,11 +327,11 @@
         CType.Int32
     ) {
         override val inKotlinSources = object : SwiftToKotlinValueConversion {
-            override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String): String = valueExpression
+            override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String): ConversionResult = valueExpression.direct()
         }
 
         override val inSwiftSources = object : SwiftToKotlinValueConversion {
-            override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String): String = "{ $valueExpression; return 0 }()"
+            override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String): ConversionResult = "{ $valueExpression; return 0 }()".direct()
         }
     }
 
@@ -327,14 +359,14 @@
                         swiftType,
                         SirTypeNamer.KotlinNameType.PARAMETRIZED
                     )
-                }"
+                }".direct()
 
             override fun kotlinToSwift(typeNamer: SirTypeNamer, valueExpression: String) =
                 "kotlin.native.internal.ref.createRetainedExternalRCRef($valueExpression)"
         }
 
         override val inSwiftSources = object : ValueConversion {
-            override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String) = "${valueExpression}.__externalRCRef()"
+            override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String) = valueExpression.externalRcRef()
 
             override fun kotlinToSwift(typeNamer: SirTypeNamer, valueExpression: String): String {
                 val swiftFqName = typeNamer.swiftFqName(swiftType)
@@ -366,7 +398,7 @@
     object AsAnyBridgeable : WithSingleType(KotlinRuntimeSupportModule.kotlinBridgeableType, KotlinType.KotlinObject, CType.Object) {
         override val inKotlinSources = object : ValueConversion {
             override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String) =
-                "kotlin.native.internal.ref.dereferenceExternalRCRef($valueExpression) as kotlin.Any"
+                "kotlin.native.internal.ref.dereferenceExternalRCRef($valueExpression) as kotlin.Any".direct()
 
             override fun kotlinToSwift(typeNamer: SirTypeNamer, valueExpression: String) =
                 "kotlin.native.internal.ref.createRetainedExternalRCRef($valueExpression)"
@@ -376,9 +408,7 @@
             override fun swiftToKotlin(
                 typeNamer: SirTypeNamer,
                 valueExpression: String,
-            ): String {
-                return "$valueExpression.__externalRCRef()"
-            }
+            ) = valueExpression.externalRcRef()
 
             override fun kotlinToSwift(typeNamer: SirTypeNamer, valueExpression: String) =
                 "${typeNamer.swiftFqName(SirNominalType(KotlinRuntimeModule.kotlinBase))}.__createProtocolWrapper(externalRCRef: $valueExpression) as! ${typeNamer.swiftFqName(swiftType)}"
@@ -406,14 +436,14 @@
                         swiftType,
                         SirTypeNamer.KotlinNameType.PARAMETRIZED
                     )
-                }"
+                }".direct()
 
             override fun kotlinToSwift(typeNamer: SirTypeNamer, valueExpression: String) =
                 "kotlin.native.internal.ref.createRetainedExternalRCRef($valueExpression)"
         }
 
         override val inSwiftSources = object : ValueConversion {
-            override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String) = "${valueExpression}.__externalRCRef()"
+            override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String) = valueExpression.externalRcRef()
 
             override fun kotlinToSwift(typeNamer: SirTypeNamer, valueExpression: String) =
                 "${typeNamer.swiftFqName(SirNominalType(KotlinRuntimeModule.kotlinBase))}.__createProtocolWrapper(externalRCRef: $valueExpression) as! ${typeNamer.swiftFqName(swiftType)}"
@@ -424,7 +454,7 @@
         override val inKotlinSources = object : ValueConversion {
             // nulls are handled by AsOptionalWrapper, so safe to cast from nullable to non-nullable
             override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String) =
-                "kotlin.native.internal.ref.dereferenceExternalRCRef($valueExpression)!!"
+                "kotlin.native.internal.ref.dereferenceExternalRCRef($valueExpression)!!".direct()
 
             override fun kotlinToSwift(typeNamer: SirTypeNamer, valueExpression: String) =
                 "kotlin.native.internal.ref.createRetainedExternalRCRef($valueExpression)"
@@ -438,8 +468,8 @@
         cType: CType,
     ) : WithSingleType(swiftType, KotlinType.ObjCObjectUnretained, cType) {
         override val inKotlinSources = object : ValueConversion {
-            override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String): String =
-                "interpretObjCPointer<${typeNamer.kotlinFqName(swiftType, SirTypeNamer.KotlinNameType.PARAMETRIZED)}>($valueExpression)"
+            override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String) =
+                "interpretObjCPointer<${typeNamer.kotlinFqName(swiftType, SirTypeNamer.KotlinNameType.PARAMETRIZED)}>($valueExpression)".direct()
 
             override fun kotlinToSwift(typeNamer: SirTypeNamer, valueExpression: String) =
                 "$valueExpression.objcPtr()"
@@ -454,9 +484,8 @@
     ) : AsObjCBridged(swiftType, CType.id) {
 
         override val inSwiftSources = object : ValueConversion {
-            override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String): String {
-                return "$valueExpression as! NSObject? ?? NSNull()"
-            }
+            override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String) =
+                "$valueExpression as! NSObject? ?? NSNull()".direct()
 
             override fun kotlinToSwift(typeNamer: SirTypeNamer, valueExpression: String): String = valueExpression
         }
@@ -471,8 +500,8 @@
                 // promotes `UInt16` (which `UTF16.CodeUnit` is) to the closest fitting signed integer storage (C int).
                 // -[NSNumber toKotlin] then produces Int box when crossing bridge,
                 // which doesn't pass strict cast checks near interpretObjCPointer
-                override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String): String =
-                    "interpretObjCPointer<Int>($valueExpression).toChar()"
+                override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String) =
+                    "interpretObjCPointer<Int>($valueExpression).toChar()".direct()
 
                 override fun kotlinToSwift(typeNamer: SirTypeNamer, valueExpression: String) =
                     "$valueExpression.objcPtr()"
@@ -483,8 +512,8 @@
 
 
         override val inSwiftSources = object : ValueConversion {
-            override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String): String =
-                "NSNumber(value: $valueExpression)"
+            override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String) =
+                "NSNumber(value: $valueExpression)".direct()
 
             override fun kotlinToSwift(typeNamer: SirTypeNamer, valueExpression: String): String {
                 require(swiftType is SirNominalType)
@@ -536,7 +565,7 @@
         cType: CType,
     ) : AsObjCBridged(swiftType, cType) {
         abstract inner class InSwiftSources : ValueConversion {
-            abstract override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String): String
+            abstract override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String): ConversionResult
 
             override fun kotlinToSwift(typeNamer: SirTypeNamer, valueExpression: String): String {
                 return "$valueExpression as! ${typeNamer.swiftFqName(swiftType)}"
@@ -546,22 +575,22 @@
 
     open class AsNSArray(swiftType: SirNominalType, elementBridge: WithSingleType) : AsNSCollection(swiftType, CType.NSArray(elementBridge.cType)) {
         override val inSwiftSources = object : InSwiftSources() {
-            override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String): String {
-                return valueExpression.mapSwift { elementBridge.inSwiftSources.swiftToKotlin(typeNamer, it) }
+            override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String): ConversionResult {
+                return valueExpression.mapSwift { elementBridge.inSwiftSources.swiftToKotlin(typeNamer, it.toString()) }
             }
         }
     }
 
     class AsNSArrayForVariadic(swiftType: SirNominalType, elementBridge: WithSingleType) : AsNSArray(swiftType, elementBridge) {
         override val inKotlinSources: ValueConversion = object : ValueConversion {
-            override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String): String {
+            override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String): ConversionResult {
                 val arrayKind = typeNamer.kotlinPrimitiveFqNameIfAny(swiftType.typeArguments.single()) ?: "Typed"
                 return "interpretObjCPointer<${
                     typeNamer.kotlinFqName(
                         swiftType,
                         SirTypeNamer.KotlinNameType.PARAMETRIZED
                     )
-                }>($valueExpression).to${arrayKind}Array()"
+                }>($valueExpression).to${arrayKind}Array()".direct()
             }
 
             override fun kotlinToSwift(typeNamer: SirTypeNamer, valueExpression: String) =
@@ -571,9 +600,9 @@
 
     class AsNSSet(swiftType: SirNominalType, elementBridge: WithSingleType) : AsNSCollection(swiftType, CType.NSSet(elementBridge.cType)) {
         override val inSwiftSources = object : InSwiftSources() {
-            override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String): String {
-                val transformedElements = valueExpression.mapSwift { elementBridge.inSwiftSources.swiftToKotlin(typeNamer, it) }
-                return if (transformedElements == valueExpression) valueExpression else "Set($transformedElements)"
+            override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String): ConversionResult {
+                val transformedElements = valueExpression.mapSwift { elementBridge.inSwiftSources.swiftToKotlin(typeNamer, it.toString()) }
+                return if (transformedElements.toString() == valueExpression) valueExpression.direct() else "Set($transformedElements)".direct()
             }
         }
     }
@@ -582,17 +611,17 @@
         AsNSCollection(swiftType, CType.NSDictionary(keyBridge.cType, valueBridge.cType)) {
 
         override val inSwiftSources = object : InSwiftSources() {
-            override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String): String {
+            override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String): ConversionResult {
                 val keyAdapter = keyBridge.inSwiftSources.swiftToKotlin(typeNamer, "key")
                 val valueAdapter = valueBridge.inSwiftSources.swiftToKotlin(typeNamer, "value")
-                return if (keyAdapter == "key" && valueAdapter == "value") {
+                return if (keyAdapter.toString() == "key" && valueAdapter.toString() == "value") {
                     valueExpression
                 } else {
                     "Dictionary(uniqueKeysWithValues: $valueExpression.map { key, value in (" +
                             "${keyBridge.inSwiftSources.swiftToKotlin(typeNamer, "key")}, " +
                             "${valueBridge.inSwiftSources.swiftToKotlin(typeNamer, "value")} " +
                             ")})"
-                }
+                }.direct()
             }
         }
     }
@@ -603,7 +632,7 @@
         CType.Void
     ) {
         override val inKotlinSources = object : ValueConversion {
-            override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String) = "null"
+            override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String) = ConversionResult.Null
             override fun kotlinToSwift(typeNamer: SirTypeNamer, valueExpression: String) = "Unit"
         }
 
@@ -630,27 +659,21 @@
 
         override val inKotlinSources: ValueConversion
             get() = object : ValueConversion {
-                override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String): String {
+                override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String): ConversionResult {
                     require(wrappedObject is SwiftToKotlinBridge)
-                    val condition = if (typeList.size > 1) {
-                        typeList.indices.joinToString(separator = " || ") { index ->
-                            val component = wrappedObject.inKotlinSources.swiftToKotlinComponent(typeNamer, valueExpression, index + 1)
-                            "$component == $NATIVE_NULL"
-                        }
+                    val wrappedResult = wrappedObject.inKotlinSources.swiftToKotlin(typeNamer, valueExpression)
+                    val condition = if (typeList.size > 1 && wrappedResult is ConversionResult.BinaryOp) {
+                        wrappedResult.replace(operator = " || ") { ConversionResult.BinaryOp(it, "==", NATIVE_NULL.direct()) }
                     } else {
-                        "$valueExpression == $NATIVE_NULL"
+                        ConversionResult.BinaryOp(valueExpression.direct(), "==", NATIVE_NULL.direct())
                     }
-                    val result = typeList.indices.joinToString(
-                        separator = wrappedObject.inKotlinSources.swiftToKotlinComponentConnector()
-                    ) { index ->
-                        val component = wrappedObject.inKotlinSources.swiftToKotlinComponent(typeNamer, valueExpression, index + 1)
-                        if (typeList.size == 1 || typeList[index].cType.unwrapAnnotated() != CType.NSNumber) {
-                            component
-                        } else {
-                            nsNumberBridge.inKotlinSources.swiftToKotlin(typeNamer, component)
-                        }
+                    val result = if (wrappedResult is ConversionResult.BinaryOp) {
+                        wrappedResult.replace { nsNumberBridge.inKotlinSources.swiftToKotlin(typeNamer, it.toString()) }
+                    } else {
+                        wrappedResult
                     }
-                    return "if ($condition) null else $result"
+
+                    return "if ($condition) null else $result".direct()
                 }
 
                 override fun kotlinToSwift(typeNamer: SirTypeNamer, valueExpression: String): String {
@@ -662,29 +685,32 @@
             }
 
         override val inSwiftSources: ValueConversion = object : ValueConversion {
-            override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String): String {
+            override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String): ConversionResult {
                 require(
                     wrappedObject is AsObjCBridged || wrappedObject is AsObject ||
                             wrappedObject is AsExistential || wrappedObject is AsAnyBridgeable || wrappedObject is AsBlock ||
                             wrappedObject is SirCustomTypeTranslatorImpl.RangeBridge
                 )
 
-                return typeList.indices.joinToString { index ->
-                    valueExpression.mapSwift {
-                        val component = wrappedObject.inSwiftSources.swiftToKotlinComponent(typeNamer, it, index + 1)
-                        if (typeList.size == 1 || typeList[index].cType.unwrapAnnotated() != CType.NSNumber) {
-                            component
+                val wrappedResult = wrappedObject.inSwiftSources.swiftToKotlin(typeNamer, valueExpression)
+                return wrappedResult.replace(operator = ", ") {
+                    val left = valueExpression.mapSwift {
+                        if (it is ConversionResult.BinaryOp) {
+                            it
                         } else {
-                            nsNumberBridge.inSwiftSources.swiftToKotlin(typeNamer, component)
+                            nsNumberBridge.inSwiftSources.swiftToKotlin(typeNamer, it.toString())
                         }
-                    } + " ?? ${wrappedObject.renderNil()}"
+                    }
+                    ConversionResult.BinaryOp(left, " ?? ", wrappedObject.renderNil().direct())
                 }
             }
 
             override fun kotlinToSwift(typeNamer: SirTypeNamer, valueExpression: String): String {
                 return when (wrappedObject) {
                     is AsObjCBridged ->
-                        valueExpression.mapSwift { wrappedObject.inSwiftSources.kotlinToSwift(typeNamer, it) }
+                        valueExpression.mapSwift {
+                            wrappedObject.inSwiftSources.kotlinToSwift(typeNamer, it.toString()).direct()
+                        }.toString()
                     is AsObject, is AsExistential, is AsAnyBridgeable, is SirCustomTypeTranslatorImpl.RangeBridge ->
                         "{ switch $valueExpression { case ${wrappedObject.renderNil()}: .none; case let res: ${
                             wrappedObject.inSwiftSources.kotlinToSwift(typeNamer, "res")
@@ -752,7 +778,7 @@
 
         override val inKotlinSources: SwiftToKotlinValueConversion
             get() = object : ValueConversion {
-                override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String): String {
+                override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String): ConversionResult {
                     val argsInClosure = parameters
                         .mapIndexed { idx, el -> "arg${idx}" to el }.takeIf { it.isNotEmpty() }
                     val defineArgs = argsInClosure
@@ -776,12 +802,12 @@
                     |        val _result = kotlinFun($callArgs)
                     |        ${returnType.inKotlinSources.swiftToKotlin(typeNamer, "_result")} 
                     |    }
-                    |}""".replaceIndentByMargin("    ")
+                    |}""".replaceIndentByMargin("    ").direct()
                 }
             }
 
         override val inSwiftSources = object : SwiftToKotlinValueConversion {
-            override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String): String {
+            override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String): ConversionResult {
                 val argsInClosure = parameters
                     .mapIndexed { idx, el -> "arg${idx}" to el }.takeIf { it.isNotEmpty() }
                 val defineArgs = argsInClosure
@@ -795,7 +821,7 @@
                 return """{
                 |    let originalBlock = $valueExpression
                 |    return {$defineArgs ${"return ${returnType.inSwiftSources.swiftToKotlin(typeNamer, "originalBlock($callArgs)")}"} }
-                |}()""".trimMargin()
+                |}()""".trimMargin().direct()
             }
         }
     }
@@ -806,8 +832,8 @@
 
         override val inSwiftSources: ValueConversion
             get() = object : ValueConversion {
-                override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String): String {
-                    return "&$valueExpression"
+                override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String): ConversionResult {
+                    return "&$valueExpression".direct()
                 }
 
                 override fun kotlinToSwift(typeNamer: SirTypeNamer, valueExpression: String): String {
diff --git a/native/swift/sir-providers/src/org/jetbrains/kotlin/sir/providers/impl/SirCustomTypeTranslatorImpl.kt b/native/swift/sir-providers/src/org/jetbrains/kotlin/sir/providers/impl/SirCustomTypeTranslatorImpl.kt
index 5649571..e73ce82d 100644
--- a/native/swift/sir-providers/src/org/jetbrains/kotlin/sir/providers/impl/SirCustomTypeTranslatorImpl.kt
+++ b/native/swift/sir-providers/src/org/jetbrains/kotlin/sir/providers/impl/SirCustomTypeTranslatorImpl.kt
@@ -214,10 +214,8 @@
             get() = typeList.first().cType
 
         override val inKotlinSources = object : ValueConversion {
-            override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String): String {
-                return listOf(1, 2).joinToString(separator = swiftToKotlinComponentConnector()) { index ->
-                    swiftToKotlinComponent(typeNamer, valueExpression, index)
-                }
+            override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String): ConversionResult {
+                return ConversionResult.BinaryOp(valueExpression.parameterX(1), if (inclusive) " .. " else " ..< ", valueExpression.parameterX(2))
             }
 
             override fun swiftToKotlinComponent(typeNamer: SirTypeNamer, valueExpression: String, index: Int): String {
@@ -233,8 +231,8 @@
         }
 
         override val inSwiftSources = object : ValueConversion {
-            override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String): String =
-                "$valueExpression.lowerBound, $valueExpression.upperBound"
+            override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String): ConversionResult =
+                ConversionResult.BinaryOp(valueExpression.property("lowerBound"), ", ", valueExpression.property("upperBound"))
 
             override fun swiftToKotlinComponent(typeNamer: SirTypeNamer, valueExpression: String, index: Int): String {
                 return when (index) {