diff --git a/SKIE/acceptance-tests b/SKIE/acceptance-tests index 3cfd3e7d..58cab739 160000 --- a/SKIE/acceptance-tests +++ b/SKIE/acceptance-tests @@ -1 +1 @@ -Subproject commit 3cfd3e7d693276e7c6d276e6812f67be38f8a62e +Subproject commit 58cab739cad270273d87b7066517e1b62eb06c8b diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/features/flow/SupportedFlow.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/features/flow/SupportedFlow.kt index 3edfaf3b..6c20cd54 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/features/flow/SupportedFlow.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/features/flow/SupportedFlow.kt @@ -32,7 +32,7 @@ enum class SupportedFlow(private val directParent: SupportedFlow?) { sealed interface Variant { - val owner: SupportedFlow + val kind: SupportedFlow fun getKotlinKirClass(kirProvider: KirProvider): KirClass @@ -46,31 +46,31 @@ enum class SupportedFlow(private val directParent: SupportedFlow?) { fun isCastableTo(variant: Variant): Boolean - class Required(override val owner: SupportedFlow) : Variant { + class Required(override val kind: SupportedFlow) : Variant { override fun getKotlinKirClass(kirProvider: KirProvider): KirClass = - kirProvider.getClassByFqName("co.touchlab.skie.runtime.coroutines.flow.SkieKotlin${owner.name}") + kirProvider.getClassByFqName("co.touchlab.skie.runtime.coroutines.flow.SkieKotlin${kind.name}") override fun getSwiftClass(sirProvider: SirProvider): SirClass = - sirProvider.getClassByFqName(SirFqName(sirProvider.skieModule, "SkieSwift${owner.name}")) + sirProvider.getClassByFqName(SirFqName(sirProvider.skieModule, "SkieSwift${kind.name}")) override fun isCastableTo(variant: Variant): Boolean { - return owner.isSelfOrChildOf(variant.owner) + return kind.isSelfOrChildOf(variant.kind) } } - class Optional(override val owner: SupportedFlow) : Variant { + class Optional(override val kind: SupportedFlow) : Variant { override fun getKotlinKirClass(kirProvider: KirProvider): KirClass = - kirProvider.getClassByFqName("co.touchlab.skie.runtime.coroutines.flow.SkieKotlinOptional${owner.name}") + kirProvider.getClassByFqName("co.touchlab.skie.runtime.coroutines.flow.SkieKotlinOptional${kind.name}") override fun getSwiftClass(sirProvider: SirProvider): SirClass = - sirProvider.getClassByFqName(SirFqName(sirProvider.skieModule, "SkieSwiftOptional${owner.name}")) + sirProvider.getClassByFqName(SirFqName(sirProvider.skieModule, "SkieSwiftOptional${kind.name}")) override fun isCastableTo(variant: Variant): Boolean { if (variant is Required) return false - return owner.isSelfOrChildOf(variant.owner) + return kind.isSelfOrChildOf(variant.kind) } } } @@ -80,6 +80,8 @@ enum class SupportedFlow(private val directParent: SupportedFlow?) { companion object { + val allVariants: List = values().flatMap { it.variants }.toList() + fun from(type: KotlinType): SupportedFlow? = (type.constructor.declarationDescriptor as? ClassDescriptor)?.let { from(it) } diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/features/suspend/SwiftSuspendGeneratorDelegate.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/features/suspend/SwiftSuspendGeneratorDelegate.kt index cca25e46..b62ba77c 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/features/suspend/SwiftSuspendGeneratorDelegate.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/features/suspend/SwiftSuspendGeneratorDelegate.kt @@ -5,6 +5,7 @@ import co.touchlab.skie.kir.element.KirSimpleFunction import co.touchlab.skie.kir.element.forEachAssociatedExportedSirDeclaration import co.touchlab.skie.phases.DescriptorModificationPhase import co.touchlab.skie.phases.SirPhase +import co.touchlab.skie.phases.features.flow.SupportedFlow import co.touchlab.skie.phases.util.doInPhase import co.touchlab.skie.sir.element.SirClass import co.touchlab.skie.sir.element.SirExtension @@ -15,12 +16,14 @@ import co.touchlab.skie.sir.element.applyToEntireOverrideHierarchy import co.touchlab.skie.sir.element.copyValueParametersFrom import co.touchlab.skie.sir.element.shallowCopy import co.touchlab.skie.sir.element.toSwiftVisibility +import co.touchlab.skie.sir.type.NullableSirType +import co.touchlab.skie.sir.type.OirDeclaredSirType +import co.touchlab.skie.sir.type.SirType import co.touchlab.skie.util.swift.addFunctionDeclarationBodyWithErrorTypeHandling import io.outfoxx.swiftpoet.AttributeSpec import io.outfoxx.swiftpoet.CodeBlock import io.outfoxx.swiftpoet.FunctionTypeName import io.outfoxx.swiftpoet.TypeName -import io.outfoxx.swiftpoet.joinToCode import org.jetbrains.kotlin.descriptors.FunctionDescriptor class SwiftSuspendGeneratorDelegate( @@ -72,18 +75,33 @@ class SwiftSuspendGeneratorDelegate( } } +context(SirPhase.Context) private fun SirExtension.createSwiftBridgingFunction(bridgeModel: BridgeModel): SirSimpleFunction = bridgeModel.originalFunction.shallowCopy( parent = this, isAsync = true, throws = true, visibility = bridgeModel.originalFunction.visibility.toSwiftVisibility(), + returnType = bridgeModel.originalFunction.returnType.revertFlowMappingIfNeeded(), ).apply { copyValueParametersFrom(bridgeModel.originalFunction) addSwiftBridgingFunctionBody(bridgeModel) } +context(SirPhase.Context) +private fun SirType.revertFlowMappingIfNeeded(): SirType { + when (this) { + is OirDeclaredSirType -> { + val flowVariant = SupportedFlow.allVariants.firstOrNull { declaration == it.getKotlinKirClass().oirClass } ?: return this + + return flowVariant.kind.getCoroutinesKirClass().originalSirClass.toType() + } + is NullableSirType -> return copy(type = type.revertFlowMappingIfNeeded()) + else -> return this + } +} + private fun SirSimpleFunction.addSwiftBridgingFunctionBody(bridgeModel: BridgeModel) { addFunctionDeclarationBodyWithErrorTypeHandling(bridgeModel.kotlinBridgingFunction) { addCode(