Skip to content

Commit 0aadb01

Browse files
mglukhikhSpace Team
authored andcommitted
Swift export: convert Kt vararg parameters as Swift variadic parameters
#KT-66838 Fixed
1 parent f4fdb44 commit 0aadb01

File tree

20 files changed

+546
-53
lines changed

20 files changed

+546
-53
lines changed

native/swift/sir-light-classes/src/org/jetbrains/sir/lightclasses/nodes/SirFunctionFromKtSymbol.kt

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -102,13 +102,15 @@ internal open class SirFunctionFromKtSymbol(
102102
}
103103

104104
override val bridges: List<SirBridge> by lazyWithSessions {
105-
listOfNotNull(bridgeProxy?.createSirBridge {
106-
val actualArgs = if (extensionReceiverParameter != null) argNames.drop(1) else argNames
107-
buildCall("(${actualArgs.joinToString()})")
108-
})
105+
listOfNotNull(
106+
bridgeProxy?.createSirBridge {
107+
val actualArgs = if (extensionReceiverParameter != null) argNames.drop(1) else argNames
108+
buildCall("(${actualArgs.joinToString()})")
109+
}
110+
)
109111
}
110112

111113
override var body: SirFunctionBody?
112-
set(value) {}
114+
set(_) {}
113115
get() = bridgeProxy?.createSwiftInvocation { "return $it" }?.let(::SirFunctionBody)
114116
}

native/swift/sir-light-classes/src/org/jetbrains/sir/lightclasses/nodes/SirInitFromKtSymbol.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ package org.jetbrains.sir.lightclasses.nodes
88
import org.jetbrains.kotlin.analysis.api.components.containingSymbol
99
import org.jetbrains.kotlin.analysis.api.components.defaultType
1010
import org.jetbrains.kotlin.analysis.api.components.isArrayOrPrimitiveArray
11-
import org.jetbrains.kotlin.analysis.api.export.utilities.isSuspend
1211
import org.jetbrains.kotlin.analysis.api.symbols.KaClassSymbol
1312
import org.jetbrains.kotlin.analysis.api.symbols.KaConstructorSymbol
1413
import org.jetbrains.kotlin.analysis.api.symbols.KaFunctionSymbol

native/swift/sir-light-classes/src/org/jetbrains/sir/lightclasses/utils/TypeTranslationUtils.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,12 @@ internal inline fun <reified T : KaFunctionSymbol> SirFromKtSymbol<T>.translateP
5353
else -> it
5454
}
5555
}
56-
SirParameter(argumentName = parameter.name.asString(), type = sirType, origin = KotlinParameterOrigin.ValueParameter(parameter))
56+
SirParameter(
57+
argumentName = parameter.name.asString(),
58+
type = sirType,
59+
origin = KotlinParameterOrigin.ValueParameter(parameter),
60+
isVariadic = parameter.isVararg,
61+
)
5762
}
5863
}
5964
}

native/swift/sir-printer/src/org/jetbrains/sir/printer/impl/SirAsSwiftSourcesPrinter.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -568,8 +568,8 @@ internal class SirAsSwiftSourcesPrinter private constructor(
568568
get() = (argumentName?.swiftIdentifier ?: "_") +
569569
(parameterName?.swiftIdentifier?.let { " $it" } ?: "") + ": " +
570570
(type.attributes.render().takeUnless { it.isBlank() }?.let { "$it " } ?: "") +
571-
type.swiftRender
572-
571+
type.swiftRender +
572+
if (isVariadic) "..." else ""
573573
}
574574

575575
private val SirVisibility.swift

native/swift/sir-providers/src/org/jetbrains/kotlin/sir/providers/SirSession.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,7 @@ public interface SirTypeNamer {
430430

431431
public fun swiftFqName(type: SirType): String
432432
public fun kotlinFqName(sirType: SirType, nameType: KotlinNameType): String
433+
public fun kotlinPrimitiveFqNameIfAny(sirType: SirType): String?
433434
}
434435

435436
public fun SirTypeNamer(): SirTypeNamer = StandaloneSirTypeNamer

native/swift/sir-providers/src/org/jetbrains/kotlin/sir/providers/impl/BridgeProvider/SirBridgeProviderImpl.kt

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import org.jetbrains.kotlin.analysis.api.KaSession
99
import org.jetbrains.kotlin.analysis.api.symbols.KaClassSymbol
1010
import org.jetbrains.kotlin.analysis.api.symbols.KaNamedClassSymbol
1111
import org.jetbrains.kotlin.builtins.StandardNames.FqNames
12-
import org.jetbrains.kotlin.name.ClassId.Companion.topLevel
1312
import org.jetbrains.kotlin.sir.*
1413
import org.jetbrains.kotlin.sir.providers.*
1514
import org.jetbrains.kotlin.sir.providers.source.kaSymbolOrNull
@@ -146,7 +145,22 @@ private class BridgeFunctionDescriptor(
146145
override val name
147146
get() = kotlinFqName.joinToString(separator = ".") { it.kotlinIdentifier }
148147

149-
override val argNames get() = this.parameters.map { "__${it.name}".kotlinIdentifier }
148+
override val argNames
149+
get() = buildList {
150+
var useNamed = false
151+
parameters.forEachIndexed { index, bridgeParameter ->
152+
val argName = buildString {
153+
if (bridgeParameter.bridge is Bridge.AsNSArrayForVariadic) {
154+
append("*")
155+
useNamed = true
156+
} else if (useNamed && bridgeParameter.isExplicit) {
157+
append("${bridgeParameter.name} = ")
158+
}
159+
append("__${bridgeParameter.name}".kotlinIdentifier)
160+
}
161+
add(argName)
162+
}
163+
}
150164

151165
override fun buildCall(args: String): String {
152166
return if (selfParameter == null) {

native/swift/sir-providers/src/org/jetbrains/kotlin/sir/providers/impl/BridgeProvider/TypeBridging.kt

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ internal fun bridgeType(type: SirType): Bridge = when (type) {
2323
else -> error("Attempt to bridge unbridgeable type: $type.")
2424
}
2525

26+
private fun bridgeTypeForVariadicParameter(type: SirType): Bridge =
27+
AsNSArrayForVariadic(SirArrayType(type), bridgeAsNSCollectionElement(type))
28+
2629
private fun bridgeExistential(type: SirExistentialType): Bridge {
2730
if (type.protocols.singleOrNull() == KotlinRuntimeSupportModule.kotlinBridgeable) {
2831
return AsAnyBridgeable
@@ -34,23 +37,23 @@ private fun bridgeExistential(type: SirExistentialType): Bridge {
3437
)
3538
}
3639

37-
private fun bridgeNominalType(type: SirNominalType): Bridge {
38-
fun bridgeAsNSCollectionElement(type: SirType): Bridge = when (val bridge = bridgeType(type)) {
39-
is AsIs -> AsNSNumber(bridge.swiftType)
40-
is AsOptionalWrapper -> AsObjCBridgedOptional(bridge.wrappedObject.swiftType)
41-
is AsOptionalNothing -> AsObjCBridgedOptional(bridge.swiftType)
42-
is AsObject,
43-
is AsExistential,
44-
is AsAnyBridgeable,
45-
is AsOpaqueObject,
46-
-> AsObjCBridged(bridge.swiftType, CType.id)
47-
is AsBlock,
48-
is AsObjCBridged,
49-
AsOutError,
50-
AsVoid
51-
-> bridge
52-
}
40+
private fun bridgeAsNSCollectionElement(type: SirType): Bridge = when (val bridge = bridgeType(type)) {
41+
is AsIs -> AsNSNumber(bridge.swiftType)
42+
is AsOptionalWrapper -> AsObjCBridgedOptional(bridge.wrappedObject.swiftType)
43+
is AsOptionalNothing -> AsObjCBridgedOptional(bridge.swiftType)
44+
is AsObject,
45+
is AsExistential,
46+
is AsAnyBridgeable,
47+
is AsOpaqueObject,
48+
-> AsObjCBridged(bridge.swiftType, CType.id)
49+
is AsBlock,
50+
is AsObjCBridged,
51+
AsOutError,
52+
AsVoid
53+
-> bridge
54+
}
5355

56+
private fun bridgeNominalType(type: SirNominalType): Bridge {
5457
return when (val subtype = type.typeDeclaration) {
5558
SirSwiftModule.void -> AsVoid
5659

@@ -127,16 +130,18 @@ private fun bridgeNominalType(type: SirNominalType): Bridge {
127130

128131
internal fun bridgeParameter(parameter: SirParameter, index: Int): BridgeParameter {
129132
val bridgeParameterName = parameter.name?.let(::createBridgeParameterName) ?: "_$index"
130-
val bridge = bridgeType(parameter.type)
133+
val bridge = if (parameter.isVariadic) bridgeTypeForVariadicParameter(parameter.type) else bridgeType(parameter.type)
131134
return BridgeParameter(
132135
name = bridgeParameterName,
133-
bridge = bridge
136+
bridge = bridge,
137+
isExplicit = parameter.origin != null,
134138
)
135139
}
136140

137141
internal data class BridgeParameter(
138142
val name: String,
139143
val bridge: Bridge,
144+
val isExplicit: Boolean = false,
140145
) {
141146
var isRenderable: Boolean = bridge !is AsOptionalNothing && bridge !is AsVoid
142147
}
@@ -409,14 +414,31 @@ internal sealed class Bridge(
409414
}
410415
}
411416

412-
class AsNSArray(swiftType: SirNominalType, elementBridge: Bridge) : AsNSCollection(swiftType, CType.NSArray(elementBridge.cType)) {
417+
open class AsNSArray(swiftType: SirNominalType, elementBridge: Bridge) : AsNSCollection(swiftType, CType.NSArray(elementBridge.cType)) {
413418
override val inSwiftSources = object : InSwiftSources() {
414419
override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String): String {
415420
return valueExpression.mapSwift { elementBridge.inSwiftSources.swiftToKotlin(typeNamer, it) }
416421
}
417422
}
418423
}
419424

425+
class AsNSArrayForVariadic(swiftType: SirNominalType, elementBridge: Bridge) : AsNSArray(swiftType, elementBridge) {
426+
override val inKotlinSources: ValueConversion = object : ValueConversion {
427+
override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String): String {
428+
val arrayKind = typeNamer.kotlinPrimitiveFqNameIfAny(swiftType.typeArguments.single()) ?: "Typed"
429+
return "interpretObjCPointer<${
430+
typeNamer.kotlinFqName(
431+
swiftType,
432+
SirTypeNamer.KotlinNameType.PARAMETRIZED
433+
)
434+
}>($valueExpression).to${arrayKind}Array()"
435+
}
436+
437+
override fun kotlinToSwift(typeNamer: SirTypeNamer, valueExpression: String) =
438+
"$valueExpression.objcPtr()"
439+
}
440+
}
441+
420442
class AsNSSet(swiftType: SirNominalType, elementBridge: Bridge) : AsNSCollection(swiftType, CType.NSSet(elementBridge.cType)) {
421443
override val inSwiftSources = object : InSwiftSources() {
422444
override fun swiftToKotlin(typeNamer: SirTypeNamer, valueExpression: String): String {

native/swift/sir-providers/src/org/jetbrains/kotlin/sir/providers/impl/SirTypeProviderImpl.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ public class SirTypeProviderImpl(
160160
if (classSymbol is KaClassSymbol && classSymbol.classKind == KaClassKind.INTERFACE) {
161161
SirExistentialType(classSymbol.toSir().allDeclarations.firstIsInstance<SirProtocol>())
162162
} else {
163-
ctx.nominalTypeFromClassSymbol(classSymbol)
163+
nominalTypeFromClassSymbol(classSymbol)
164164
}
165165
is SirAvailability.Unavailable -> null
166166
}
@@ -266,7 +266,9 @@ public class SirTypeProviderImpl(
266266
return this
267267
}
268268

269-
private fun TypeTranslationCtx.nominalTypeFromClassSymbol(symbol: KaClassLikeSymbol): SirNominalType? = sirSession.withSessions {
269+
private fun nominalTypeFromClassSymbol(
270+
symbol: KaClassLikeSymbol,
271+
): SirNominalType? = sirSession.withSessions {
270272
symbol.toSir().allDeclarations.firstIsInstanceOrNull<SirScopeDefiningDeclaration>()?.let(::SirNominalType)
271273
}
272274

native/swift/sir-providers/src/org/jetbrains/kotlin/sir/providers/impl/SirVisibilityCheckerImpl.kt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,6 @@ public class SirVisibilityCheckerImpl(
8585
if (ktSymbol is KaCallableSymbol && ktSymbol.contextParameters.isNotEmpty()) {
8686
return@withSessions SirAvailability.Unavailable("Callables with context parameters are not supported yet")
8787
}
88-
if (ktSymbol is KaFunctionSymbol && ktSymbol.valueParameters.any { it.isVararg }) {
89-
return@withSessions SirAvailability.Unavailable("Callables with vararg parameters are not supported yet")
90-
}
9188
if (ktSymbol is KaNamedFunctionSymbol && ktSymbol.allParameters.map { it.returnType.fullyExpandedType }
9289
.filter { type -> !type.isFunctionType && speciallyBridgedTypes.none { type.isClassType(it) } }
9390
.any { hasUnboundTypeParameters(it) }

native/swift/sir-providers/src/org/jetbrains/kotlin/sir/providers/impl/StandaloneSirTypeNamer.kt

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.sir.SirErrorType
1313
import org.jetbrains.kotlin.sir.SirExistentialType
1414
import org.jetbrains.kotlin.sir.SirFunctionalType
1515
import org.jetbrains.kotlin.sir.SirNominalType
16+
import org.jetbrains.kotlin.sir.SirScopeDefiningDeclaration
1617
import org.jetbrains.kotlin.sir.SirType
1718
import org.jetbrains.kotlin.sir.SirUnsupportedType
1819
import org.jetbrains.kotlin.sir.providers.SirTypeNamer
@@ -30,6 +31,33 @@ internal object StandaloneSirTypeNamer : SirTypeNamer {
3031
SirTypeNamer.KotlinNameType.PARAMETRIZED -> kotlinParametrizedName(sirType)
3132
}
3233

34+
override fun kotlinPrimitiveFqNameIfAny(sirType: SirType): String? {
35+
return (sirType as? SirNominalType)?.typeDeclaration?.primitiveFqNameIfAny()
36+
}
37+
38+
private fun SirScopeDefiningDeclaration.primitiveFqNameIfAny(): String? {
39+
return primitiveFqNameMap[this]
40+
}
41+
42+
private val primitiveFqNameMap = hashMapOf<SirScopeDefiningDeclaration, String>(
43+
SirSwiftModule.bool to "Boolean",
44+
45+
SirSwiftModule.int8 to "Byte",
46+
SirSwiftModule.int16 to "Short",
47+
SirSwiftModule.int32 to "Int",
48+
SirSwiftModule.int64 to "Long",
49+
50+
SirSwiftModule.uint8 to "UByte",
51+
SirSwiftModule.uint16 to "UShort",
52+
SirSwiftModule.uint32 to "UInt",
53+
SirSwiftModule.uint64 to "ULong",
54+
55+
SirSwiftModule.double to "Double",
56+
SirSwiftModule.float to "Float",
57+
58+
SirSwiftModule.utf16CodeUnit to "Char",
59+
)
60+
3361
private fun kotlinFqName(type: SirType): String = when (type) {
3462
is SirNominalType -> kotlinFqName(type)
3563
is SirExistentialType -> kotlinFqName(type)
@@ -49,29 +77,14 @@ internal object StandaloneSirTypeNamer : SirTypeNamer {
4977

5078
@OptIn(KaExperimentalApi::class)
5179
private fun kotlinFqName(type: SirNominalType): String {
52-
return when (val declaration = type.typeDeclaration) {
80+
val declaration = type.typeDeclaration
81+
declaration.primitiveFqNameIfAny()?.let { return it }
82+
return when (declaration) {
5383
KotlinRuntimeModule.kotlinBase -> "kotlin.Any"
5484
KotlinRuntimeSupportModule.kotlinBridgeable -> "kotlin.Any"
5585
SirSwiftModule.anyHashable -> "kotlin.Any"
5686
SirSwiftModule.string -> "kotlin.String"
5787

58-
SirSwiftModule.bool -> "Boolean"
59-
60-
SirSwiftModule.int8 -> "Byte"
61-
SirSwiftModule.int16 -> "Short"
62-
SirSwiftModule.int32 -> "Int"
63-
SirSwiftModule.int64 -> "Long"
64-
65-
SirSwiftModule.uint8 -> "UByte"
66-
SirSwiftModule.uint16 -> "UShort"
67-
SirSwiftModule.uint32 -> "UInt"
68-
SirSwiftModule.uint64 -> "ULong"
69-
70-
SirSwiftModule.double -> "Double"
71-
SirSwiftModule.float -> "Float"
72-
73-
SirSwiftModule.utf16CodeUnit -> "Char"
74-
7588
SirSwiftModule.unsafeMutableRawPointer -> "kotlin.native.internal.NativePtr"
7689

7790
SirSwiftModule.void -> "Void"

0 commit comments

Comments
 (0)