[K/N] Extract ObjcOverridabilityCondition to separate file
^Kt-61511
This commit is contained in:
committed by
Space Team
parent
4c15509776
commit
202f30f910
@@ -188,70 +188,6 @@ fun IrFunction.isObjCBridgeBased(): Boolean {
|
|||||||
this.annotations.hasAnnotation(objCConstructorFqName)
|
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 =
|
fun IrConstructor.objCConstructorIsDesignated(): Boolean =
|
||||||
this.getAnnotationArgumentValue<Boolean>(objCConstructorFqName, "designated")
|
this.getAnnotationArgumentValue<Boolean>(objCConstructorFqName, "designated")
|
||||||
?: error("Could not find 'designated' argument")
|
?: error("Could not find 'designated' argument")
|
||||||
|
|||||||
+78
@@ -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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user