From 202f30f910483c5ebf656ec0e1e7ebdc36129524 Mon Sep 17 00:00:00 2001 From: Pavel Kunyavskiy Date: Sun, 8 Oct 2023 13:40:43 +0200 Subject: [PATCH] [K/N] Extract ObjcOverridabilityCondition to separate file ^Kt-61511 --- .../kotlin/ir/objcinterop/ObjCInterop.kt | 64 --------------- .../ObjCOverridabilityCondition.kt | 78 +++++++++++++++++++ 2 files changed, 78 insertions(+), 64 deletions(-) create mode 100644 compiler/ir/ir.objcinterop/src/org/jetbrains/kotlin/ir/objcinterop/ObjCOverridabilityCondition.kt diff --git a/compiler/ir/ir.objcinterop/src/org/jetbrains/kotlin/ir/objcinterop/ObjCInterop.kt b/compiler/ir/ir.objcinterop/src/org/jetbrains/kotlin/ir/objcinterop/ObjCInterop.kt index 447f976fa0d..b50d21eed8e 100644 --- a/compiler/ir/ir.objcinterop/src/org/jetbrains/kotlin/ir/objcinterop/ObjCInterop.kt +++ b/compiler/ir/ir.objcinterop/src/org/jetbrains/kotlin/ir/objcinterop/ObjCInterop.kt @@ -188,70 +188,6 @@ fun IrFunction.isObjCBridgeBased(): Boolean { this.annotations.hasAnnotation(objCConstructorFqName) } -/** - * Describes method overriding rules for Objective-C methods. - * - * This class is applied at [org.jetbrains.kotlin.resolve.OverridingUtil] as configured with - * `META-INF/services/org.jetbrains.kotlin.resolve.ExternalOverridabilityCondition` resource. - */ -class ObjCOverridabilityCondition : ExternalOverridabilityCondition { - - override fun getContract() = ExternalOverridabilityCondition.Contract.BOTH - - override fun isOverridable( - superDescriptor: CallableDescriptor, - subDescriptor: CallableDescriptor, - subClassDescriptor: ClassDescriptor? - ): ExternalOverridabilityCondition.Result { - if (superDescriptor.name == subDescriptor.name) { // Slow path: - if (superDescriptor is FunctionDescriptor && subDescriptor is FunctionDescriptor) { - superDescriptor.getExternalObjCMethodInfo()?.let { superInfo -> - val subInfo = subDescriptor.getExternalObjCMethodInfo() - if (subInfo != null) { - // Overriding Objective-C method by Objective-C method in interop stubs. - // Don't even check method signatures: - return if (superInfo.selector == subInfo.selector) { - ExternalOverridabilityCondition.Result.OVERRIDABLE - } else { - ExternalOverridabilityCondition.Result.INCOMPATIBLE - } - } else { - // Overriding Objective-C method by Kotlin method. - if (!parameterNamesMatch(superDescriptor, subDescriptor)) { - return ExternalOverridabilityCondition.Result.INCOMPATIBLE - } - } - } - } else if (superDescriptor.isExternalObjCClassProperty() && subDescriptor.isExternalObjCClassProperty()) { - return ExternalOverridabilityCondition.Result.OVERRIDABLE - } - } - - return ExternalOverridabilityCondition.Result.UNKNOWN - } - - private fun CallableDescriptor.isExternalObjCClassProperty() = this is PropertyDescriptor && - (this.containingDeclaration as? ClassDescriptor)?.isExternalObjCClass() == true - - private fun parameterNamesMatch(first: FunctionDescriptor, second: FunctionDescriptor): Boolean { - // The original Objective-C method selector is represented as - // function name and parameter names (except first). - - if (first.valueParameters.size != second.valueParameters.size) { - return false - } - - first.valueParameters.forEachIndexed { index, parameter -> - if (index > 0 && parameter.name != second.valueParameters[index].name) { - return false - } - } - - return true - } - -} - fun IrConstructor.objCConstructorIsDesignated(): Boolean = this.getAnnotationArgumentValue(objCConstructorFqName, "designated") ?: error("Could not find 'designated' argument") diff --git a/compiler/ir/ir.objcinterop/src/org/jetbrains/kotlin/ir/objcinterop/ObjCOverridabilityCondition.kt b/compiler/ir/ir.objcinterop/src/org/jetbrains/kotlin/ir/objcinterop/ObjCOverridabilityCondition.kt new file mode 100644 index 00000000000..bb044200a5a --- /dev/null +++ b/compiler/ir/ir.objcinterop/src/org/jetbrains/kotlin/ir/objcinterop/ObjCOverridabilityCondition.kt @@ -0,0 +1,78 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.ir.objcinterop + +import org.jetbrains.kotlin.descriptors.CallableDescriptor +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.FunctionDescriptor +import org.jetbrains.kotlin.descriptors.PropertyDescriptor +import org.jetbrains.kotlin.resolve.ExternalOverridabilityCondition + +/** + * Describes method overriding rules for Objective-C methods. + * + * This class is applied at [org.jetbrains.kotlin.resolve.OverridingUtil] as configured with + * `META-INF/services/org.jetbrains.kotlin.resolve.ExternalOverridabilityCondition` resource. + * + * + */ +class ObjCOverridabilityCondition : ExternalOverridabilityCondition { + + override fun getContract() = ExternalOverridabilityCondition.Contract.BOTH + + override fun isOverridable( + superDescriptor: CallableDescriptor, + subDescriptor: CallableDescriptor, + subClassDescriptor: ClassDescriptor? + ): ExternalOverridabilityCondition.Result { + if (superDescriptor.name == subDescriptor.name) { // Slow path: + if (superDescriptor is FunctionDescriptor && subDescriptor is FunctionDescriptor) { + superDescriptor.getExternalObjCMethodInfo()?.let { superInfo -> + val subInfo = subDescriptor.getExternalObjCMethodInfo() + if (subInfo != null) { + // Overriding Objective-C method by Objective-C method in interop stubs. + // Don't even check method signatures: + return if (superInfo.selector == subInfo.selector) { + ExternalOverridabilityCondition.Result.OVERRIDABLE + } else { + ExternalOverridabilityCondition.Result.INCOMPATIBLE + } + } else { + // Overriding Objective-C method by Kotlin method. + if (!parameterNamesMatch(superDescriptor, subDescriptor)) { + return ExternalOverridabilityCondition.Result.INCOMPATIBLE + } + } + } + } else if (superDescriptor.isExternalObjCClassProperty() && subDescriptor.isExternalObjCClassProperty()) { + return ExternalOverridabilityCondition.Result.OVERRIDABLE + } + } + + return ExternalOverridabilityCondition.Result.UNKNOWN + } + + private fun CallableDescriptor.isExternalObjCClassProperty() = this is PropertyDescriptor && + (this.containingDeclaration as? ClassDescriptor)?.isExternalObjCClass() == true + + private fun parameterNamesMatch(first: FunctionDescriptor, second: FunctionDescriptor): Boolean { + // The original Objective-C method selector is represented as + // function name and parameter names (except first). + + if (first.valueParameters.size != second.valueParameters.size) { + return false + } + + first.valueParameters.forEachIndexed { index, parameter -> + if (index > 0 && parameter.name != second.valueParameters[index].name) { + return false + } + } + + return true + } + +} \ No newline at end of file