Skip to content

Commit

Permalink
Fix support for ShouldRefineInSwift annotation.
Browse files Browse the repository at this point in the history
  • Loading branch information
FilipDolnik committed Nov 23, 2023
1 parent ff5ddfc commit f7dfcb4
Show file tree
Hide file tree
Showing 16 changed files with 54 additions and 25 deletions.
2 changes: 1 addition & 1 deletion SKIE/acceptance-tests
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ sealed interface KirCallableDeclaration<S : SirCallableDeclaration> : KirElement

val oirCallableDeclaration: OirCallableDeclaration

val isRefinedInSwift: Boolean

val module: KirModule
get() = owner.module

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class KirProperty(
var type: KirType,
val isVar: Boolean,
override val deprecationLevel: DeprecationLevel,
override val isRefinedInSwift: Boolean,
) : KirOverridableDeclaration<KirProperty, SirProperty> {

val name: String
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class KirSimpleFunction(
override val scope: KirScope,
override val errorHandlingStrategy: OirFunction.ErrorHandlingStrategy,
override val deprecationLevel: DeprecationLevel,
override val isRefinedInSwift: Boolean,
) : KirFunction<SirSimpleFunction>(), KirOverridableDeclaration<KirSimpleFunction, SirSimpleFunction> {

lateinit var oirSimpleFunction: OirSimpleFunction
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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"
}
}
}
Expand All @@ -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)
Expand Down Expand Up @@ -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<SirSimpleFunction> =
// 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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,
Expand Down Expand Up @@ -154,6 +156,7 @@ class CreateKirMembersPhase(
scope = kirClass.callableDeclarationScope,
errorHandlingStrategy = methodBridge.returnBridge.errorHandlingStrategy,
deprecationLevel = descriptor.kirDeprecationLevel,
isRefinedInSwift = baseDescriptor.isRefinedInSwift,
)

getDirectParents(descriptor)
Expand Down Expand Up @@ -202,6 +205,7 @@ class CreateKirMembersPhase(
type = kirTypeTranslator.mapReturnType(originalDescriptor.getter!!, getterBridge.returnBridge),
isVar = descriptor.isVar,
deprecationLevel = descriptor.kirDeprecationLevel,
isRefinedInSwift = baseDescriptor.isRefinedInSwift,
)

getDirectParents(descriptor)
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ object RenameCallableDeclarationsConflictingWithTypeDeclarationsPhase : SirPhase
context(SirPhase.Context)
private fun SirCallableDeclaration.renameIfConflictsWith(reservedNames: Set<String>) {
this.resolveCollisionWithWarning {
if (identifierAfterVisibilityChanges in reservedNames) "a type name '$identifierAfterVisibilityChanges'" else null
if (identifierAfterVisibilityChange in reservedNames) "a type name '$identifierAfterVisibilityChange'" else null
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -56,6 +57,7 @@ class CreateSirMembersPhase(
parent = constructor.getSirParent(),
throws = constructor.errorHandlingStrategy.isThrowing,
deprecationLevel = constructor.deprecationLevel,
visibility = constructor.visibility,
).apply {
createValueParameters(constructor, constructor.swiftFunctionName)
}
Expand All @@ -74,6 +76,7 @@ class CreateSirMembersPhase(
scope = oirSimpleFunction.scope.sirScope,
throws = function.errorHandlingStrategy.isThrowing,
deprecationLevel = function.deprecationLevel,
visibility = function.visibility,
).apply {
createValueParameters(function, swiftFunctionName)
}
Expand All @@ -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(
Expand Down Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ object GenerateSirFileCodePhase : SirPhase {
}

addFunction(
FunctionSpec.builder(function.identifier)
FunctionSpec.builder(function.identifierAfterVisibilityChange)
.addFunctionProperties(function)
.addOverrideIfNeeded(function)
.addScope(function)
Expand All @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class SirConstructor(

override val identifier = "init"

override val identifierAfterVisibilityChanges: String
override val identifierAfterVisibilityChange: String
get() = identifier

override val identifierForReference: String
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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}:" }})"
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ class SirSimpleFunction(
override val deprecationLevel: DeprecationLevel = DeprecationLevel.None,
) : SirFunction(attributes.toMutableList(), modifiers.toMutableList()), SirTypeParameterParent, SirOverridableDeclaration<SirSimpleFunction> {

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)

Expand Down

0 comments on commit f7dfcb4

Please sign in to comment.