From f7dfcb4170b016c2e24181e486679a057906af54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Doln=C3=ADk?= Date: Thu, 23 Nov 2023 09:15:24 +0100 Subject: [PATCH] Fix support for ShouldRefineInSwift annotation. --- SKIE/acceptance-tests | 2 +- .../kir/element/KirCallableDeclaration.kt | 2 ++ .../skie/kir/element/KirConstructor.kt | 2 ++ .../touchlab/skie/kir/element/KirProperty.kt | 1 + .../skie/kir/element/KirSimpleFunction.kt | 1 + .../suspend/SwiftSuspendGeneratorDelegate.kt | 23 +++++++++++-------- .../skie/phases/kir/CreateKirMembersPhase.kt | 9 ++++++++ ...onsConflictingWithTypeDeclarationsPhase.kt | 2 +- .../skie/phases/memberconflicts/Signature.kt | 4 ++-- .../sir/member/CreateSirMembersPhase.kt | 11 +++++++++ .../phases/swift/GenerateSirFileCodePhase.kt | 4 ++-- .../sir/element/SirCallableDeclaration.kt | 2 +- .../skie/sir/element/SirConstructor.kt | 2 +- .../touchlab/skie/sir/element/SirFunction.kt | 4 ++-- .../touchlab/skie/sir/element/SirProperty.kt | 6 ++--- .../skie/sir/element/SirSimpleFunction.kt | 4 ++-- 16 files changed, 54 insertions(+), 25 deletions(-) diff --git a/SKIE/acceptance-tests b/SKIE/acceptance-tests index 930e672f..3bfd56d1 160000 --- a/SKIE/acceptance-tests +++ b/SKIE/acceptance-tests @@ -1 +1 @@ -Subproject commit 930e672fd98eb51b22a70a8c11556d2f75672431 +Subproject commit 3bfd56d191af7d12bf3aa685cece43a029059ac6 diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/kir/element/KirCallableDeclaration.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/kir/element/KirCallableDeclaration.kt index dd9ff6cf..89633212 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/kir/element/KirCallableDeclaration.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/kir/element/KirCallableDeclaration.kt @@ -23,6 +23,8 @@ sealed interface KirCallableDeclaration : KirElement val oirCallableDeclaration: OirCallableDeclaration + val isRefinedInSwift: Boolean + val module: KirModule get() = owner.module diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/kir/element/KirConstructor.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/kir/element/KirConstructor.kt index 976558a3..eafa3cc8 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/kir/element/KirConstructor.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/kir/element/KirConstructor.kt @@ -18,6 +18,8 @@ class KirConstructor( override val scope: KirScope = KirScope.Static + override val isRefinedInSwift: Boolean = false + override val origin: KirCallableDeclaration.Origin = KirCallableDeclaration.Origin.Member lateinit var oirConstructor: OirConstructor diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/kir/element/KirProperty.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/kir/element/KirProperty.kt index d240c91e..9ca56ea6 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/kir/element/KirProperty.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/kir/element/KirProperty.kt @@ -16,6 +16,7 @@ class KirProperty( var type: KirType, val isVar: Boolean, override val deprecationLevel: DeprecationLevel, + override val isRefinedInSwift: Boolean, ) : KirOverridableDeclaration { val name: String diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/kir/element/KirSimpleFunction.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/kir/element/KirSimpleFunction.kt index af4984e6..675f31da 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/kir/element/KirSimpleFunction.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/kir/element/KirSimpleFunction.kt @@ -20,6 +20,7 @@ class KirSimpleFunction( override val scope: KirScope, override val errorHandlingStrategy: OirFunction.ErrorHandlingStrategy, override val deprecationLevel: DeprecationLevel, + override val isRefinedInSwift: Boolean, ) : KirFunction(), KirOverridableDeclaration { lateinit var oirSimpleFunction: OirSimpleFunction 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 b62ba77c..1977a9fb 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 @@ -2,7 +2,6 @@ package co.touchlab.skie.phases.features.suspend import co.touchlab.skie.kir.element.KirClass 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 @@ -15,7 +14,6 @@ import co.touchlab.skie.sir.element.SirVisibility 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 @@ -47,19 +45,21 @@ class SwiftSuspendGeneratorDelegate( parent = skieNamespaceProvider.getNamespaceFile(bridgeModel.suspendFunctionOwner), ) - markOriginalFunctionAsReplaced(bridgeModel.suspendKirFunction) - bridgeModel.suspendKirFunction.bridgedSirFunction = extension.createSwiftBridgingFunction(bridgeModel) + + hideOriginalFunction(bridgeModel) } } context(SirPhase.Context) - private fun markOriginalFunctionAsReplaced( - suspendKirFunction: KirSimpleFunction, - ) { - suspendKirFunction.forEachAssociatedExportedSirDeclaration { + private fun hideOriginalFunction(bridgeModel: BridgeModel) { + bridgeModel.suspendKirFunctionAssociatedDeclarations.forEach { it.applyToEntireOverrideHierarchy { - visibility = SirVisibility.PublicButReplaced + // Cannot use PublicButReplaced because the function might be annotated with @ShouldRefineInSwift + if (visibility == SirVisibility.Public) { + visibility = SirVisibility.PublicButHidden + } + identifier = "__$identifier" } } } @@ -81,7 +81,6 @@ private fun SirExtension.createSwiftBridgingFunction(bridgeModel: BridgeModel): parent = this, isAsync = true, throws = true, - visibility = bridgeModel.originalFunction.visibility.toSwiftVisibility(), returnType = bridgeModel.originalFunction.returnType.revertFlowMappingIfNeeded(), ).apply { copyValueParametersFrom(bridgeModel.originalFunction) @@ -190,6 +189,10 @@ private data class BridgeModel( val originalFunction: SirSimpleFunction = suspendKirFunction.bridgedSirFunction ?: error("Suspend function $suspendKirFunction does not have an async bridge.") + val suspendKirFunctionAssociatedDeclarations: List = + // TODO Change after bridged declarations are replaced with async function + listOfNotNull(suspendKirFunction.originalSirFunction, suspendKirFunction.bridgedSirFunction) + val kotlinBridgingFunction: SirSimpleFunction = kotlinBridgingKirFunction.originalSirFunction val kotlinBridgingFunctionOwner: SirClass = kotlinBridgingKirFunction.owner.originalSirClass diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/kir/CreateKirMembersPhase.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/kir/CreateKirMembersPhase.kt index dbf6dbb1..0b48a512 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/kir/CreateKirMembersPhase.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/kir/CreateKirMembersPhase.kt @@ -15,6 +15,7 @@ import co.touchlab.skie.kir.element.KirValueParameter import co.touchlab.skie.kir.util.addOverrides import co.touchlab.skie.oir.element.OirFunction import co.touchlab.skie.phases.SirPhase +import org.jetbrains.kotlin.backend.konan.KonanFqNames import org.jetbrains.kotlin.backend.konan.objcexport.MethodBridge import org.jetbrains.kotlin.backend.konan.objcexport.MethodBridgeValueParameter import org.jetbrains.kotlin.backend.konan.objcexport.getDeprecation @@ -31,6 +32,7 @@ import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor import org.jetbrains.kotlin.descriptors.SourceFile import org.jetbrains.kotlin.resolve.deprecation.DeprecationLevelValue +import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass class CreateKirMembersPhase( context: SirPhase.Context, @@ -154,6 +156,7 @@ class CreateKirMembersPhase( scope = kirClass.callableDeclarationScope, errorHandlingStrategy = methodBridge.returnBridge.errorHandlingStrategy, deprecationLevel = descriptor.kirDeprecationLevel, + isRefinedInSwift = baseDescriptor.isRefinedInSwift, ) getDirectParents(descriptor) @@ -202,6 +205,7 @@ class CreateKirMembersPhase( type = kirTypeTranslator.mapReturnType(originalDescriptor.getter!!, getterBridge.returnBridge), isVar = descriptor.isVar, deprecationLevel = descriptor.kirDeprecationLevel, + isRefinedInSwift = baseDescriptor.isRefinedInSwift, ) getDirectParents(descriptor) @@ -273,6 +277,11 @@ class CreateKirMembersPhase( } } + private val CallableMemberDescriptor.isRefinedInSwift: Boolean + get() = annotations.any { annotation -> + annotation.annotationClass?.annotations?.any { it.fqName == KonanFqNames.refinesInSwift } == true + } + private val MethodBridge.ReturnValue.errorHandlingStrategy: OirFunction.ErrorHandlingStrategy get() = when (this) { MethodBridge.ReturnValue.WithError.Success -> OirFunction.ErrorHandlingStrategy.ReturnsBoolean diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/memberconflicts/RenameCallableDeclarationsConflictingWithTypeDeclarationsPhase.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/memberconflicts/RenameCallableDeclarationsConflictingWithTypeDeclarationsPhase.kt index 95823d63..4916719b 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/memberconflicts/RenameCallableDeclarationsConflictingWithTypeDeclarationsPhase.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/memberconflicts/RenameCallableDeclarationsConflictingWithTypeDeclarationsPhase.kt @@ -25,7 +25,7 @@ object RenameCallableDeclarationsConflictingWithTypeDeclarationsPhase : SirPhase context(SirPhase.Context) private fun SirCallableDeclaration.renameIfConflictsWith(reservedNames: Set) { this.resolveCollisionWithWarning { - if (identifierAfterVisibilityChanges in reservedNames) "a type name '$identifierAfterVisibilityChanges'" else null + if (identifierAfterVisibilityChange in reservedNames) "a type name '$identifierAfterVisibilityChange'" else null } } } diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/memberconflicts/Signature.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/memberconflicts/Signature.kt index c543872d..8913126a 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/memberconflicts/Signature.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/memberconflicts/Signature.kt @@ -290,7 +290,7 @@ sealed class Signature { operator fun invoke(function: SirSimpleFunction): Signature = SimpleFunction( receiver = function.receiver, - identifier = function.identifierAfterVisibilityChanges, + identifier = function.identifierAfterVisibilityChange, valueParameters = function.signatureValueParameters, returnType = ReturnType.Specific(function.returnType.signatureType), scope = function.signatureScope, @@ -312,7 +312,7 @@ sealed class Signature { operator fun invoke(property: SirProperty): Signature = Property( receiver = property.receiver, - identifier = property.identifierAfterVisibilityChanges, + identifier = property.identifierAfterVisibilityChange, scope = property.signatureScope, ) diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/sir/member/CreateSirMembersPhase.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/sir/member/CreateSirMembersPhase.kt index 4c7cd174..21a9c612 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/sir/member/CreateSirMembersPhase.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/sir/member/CreateSirMembersPhase.kt @@ -21,6 +21,7 @@ import co.touchlab.skie.sir.element.SirScope import co.touchlab.skie.sir.element.SirSetter import co.touchlab.skie.sir.element.SirSimpleFunction import co.touchlab.skie.sir.element.SirValueParameter +import co.touchlab.skie.sir.element.SirVisibility import co.touchlab.skie.util.collisionFreeIdentifier import co.touchlab.skie.util.swift.toValidSwiftIdentifier @@ -56,6 +57,7 @@ class CreateSirMembersPhase( parent = constructor.getSirParent(), throws = constructor.errorHandlingStrategy.isThrowing, deprecationLevel = constructor.deprecationLevel, + visibility = constructor.visibility, ).apply { createValueParameters(constructor, constructor.swiftFunctionName) } @@ -74,6 +76,7 @@ class CreateSirMembersPhase( scope = oirSimpleFunction.scope.sirScope, throws = function.errorHandlingStrategy.isThrowing, deprecationLevel = function.deprecationLevel, + visibility = function.visibility, ).apply { createValueParameters(function, swiftFunctionName) } @@ -90,6 +93,7 @@ class CreateSirMembersPhase( type = sirTypeTranslator.mapType(oirProperty.type), scope = oirProperty.scope.sirScope, deprecationLevel = property.deprecationLevel, + visibility = property.visibility, ).apply { property.descriptor.getter?.let { SirGetter( @@ -154,6 +158,13 @@ class CreateSirMembersPhase( } } + private val KirCallableDeclaration<*>.visibility: SirVisibility + get() = if (this.isRefinedInSwift) { + SirVisibility.PublicButReplaced + } else { + SirVisibility.Public + } + private val KirFunction<*>.swiftFunctionName: SwiftFunctionName get() { val swiftName = namer.getSwiftName(this.baseDescriptor) diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/swift/GenerateSirFileCodePhase.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/swift/GenerateSirFileCodePhase.kt index 10bf9d88..4e6f5578 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/swift/GenerateSirFileCodePhase.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/phases/swift/GenerateSirFileCodePhase.kt @@ -266,7 +266,7 @@ object GenerateSirFileCodePhase : SirPhase { } addFunction( - FunctionSpec.builder(function.identifier) + FunctionSpec.builder(function.identifierAfterVisibilityChange) .addFunctionProperties(function) .addOverrideIfNeeded(function) .addScope(function) @@ -283,7 +283,7 @@ object GenerateSirFileCodePhase : SirPhase { } addProperty( - PropertySpec.builder(property.identifier, property.type.toSwiftPoetTypeName()) + PropertySpec.builder(property.identifierAfterVisibilityChange, property.type.toSwiftPoetTypeName()) .addCallableDeclarationProperties(property) .addOverrideIfNeeded(property) .addScope(property) diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirCallableDeclaration.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirCallableDeclaration.kt index 7633cc5d..566c181d 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirCallableDeclaration.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirCallableDeclaration.kt @@ -20,7 +20,7 @@ sealed interface SirCallableDeclaration : SirDeclaration, SirElementWithModifier * foo * __foo (visibility == PublicButReplaced && !constructor) */ - val identifierAfterVisibilityChanges: String + val identifierAfterVisibilityChange: String /** * Use to obtain declaration `reference` in generated Swift code. diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirConstructor.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirConstructor.kt index 7daf90ba..6271b4f9 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirConstructor.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirConstructor.kt @@ -16,7 +16,7 @@ class SirConstructor( override val identifier = "init" - override val identifierAfterVisibilityChanges: String + override val identifierAfterVisibilityChange: String get() = identifier override val identifierForReference: String diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirFunction.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirFunction.kt index 3fdfd8a9..f1230928 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirFunction.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirFunction.kt @@ -25,9 +25,9 @@ sealed class SirFunction( override val name: String get() = if (valueParameters.isEmpty()) { - "$identifierAfterVisibilityChanges()" + "$identifierAfterVisibilityChange()" } else { - "$identifierAfterVisibilityChanges(${valueParameters.joinToString("") { "${it.labelOrName}:" }})" + "$identifierAfterVisibilityChange(${valueParameters.joinToString("") { "${it.labelOrName}:" }})" } /** diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirProperty.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirProperty.kt index 06695f10..b22cf810 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirProperty.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirProperty.kt @@ -20,17 +20,17 @@ class SirProperty( override val parent: SirDeclarationParent by sirDeclarationParent(parent) - override val identifierAfterVisibilityChanges: String + override val identifierAfterVisibilityChange: String get() = when (visibility) { SirVisibility.PublicButReplaced -> "__$identifier" else -> identifier } override val reference: String - get() = CodeBlock.toString("%N", identifierAfterVisibilityChanges) + get() = CodeBlock.toString("%N", identifierAfterVisibilityChange) override val name: String - get() = identifierAfterVisibilityChanges + get() = identifierAfterVisibilityChange var getter: SirGetter? = null private set diff --git a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirSimpleFunction.kt b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirSimpleFunction.kt index 426227ce..c52d4c4b 100644 --- a/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirSimpleFunction.kt +++ b/SKIE/compiler/kotlin-plugin/src/kgp_common/kotlin/co/touchlab/skie/sir/element/SirSimpleFunction.kt @@ -20,14 +20,14 @@ class SirSimpleFunction( override val deprecationLevel: DeprecationLevel = DeprecationLevel.None, ) : SirFunction(attributes.toMutableList(), modifiers.toMutableList()), SirTypeParameterParent, SirOverridableDeclaration { - override val identifierAfterVisibilityChanges: String + override val identifierAfterVisibilityChange: String get() = when (visibility) { SirVisibility.PublicButReplaced -> "__$identifier" else -> identifier } override val identifierForReference: String - get() = CodeBlock.toString("%N", identifierAfterVisibilityChanges) + get() = CodeBlock.toString("%N", identifierAfterVisibilityChange) override var parent: SirDeclarationParent by sirDeclarationParent(parent)