[Commonizer] Keep parameters names hash in approximation keys for ObjC callables

^KT-34602
This commit is contained in:
Dmitriy Dolovov
2020-08-13 11:53:51 +07:00
parent 3b901a28d5
commit de0b6e06cf
2 changed files with 30 additions and 9 deletions
@@ -5,16 +5,12 @@
package org.jetbrains.kotlin.descriptors.commonizer.mergedtree
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirTypeSignature
import org.jetbrains.kotlin.descriptors.commonizer.core.Commonizer
import org.jetbrains.kotlin.descriptors.commonizer.utils.*
import org.jetbrains.kotlin.descriptors.commonizer.utils.intern
import org.jetbrains.kotlin.descriptors.commonizer.utils.signature
import org.jetbrains.kotlin.descriptors.commonizer.utils.hashCode
import org.jetbrains.kotlin.descriptors.commonizer.utils.appendHashCode
import org.jetbrains.kotlin.name.Name
/** Used for approximation of [PropertyDescriptor]s before running concrete [Commonizer]s */
@@ -32,11 +28,13 @@ data class PropertyApproximationKey(
class FunctionApproximationKey(
private val name: Name,
private val valueParametersTypes: Array<CirTypeSignature>,
private val additionalValueParametersNamesHash: Int,
private val extensionReceiverParameterType: CirTypeSignature?
) {
constructor(function: SimpleFunctionDescriptor) : this(
function.name.intern(),
function.valueParameters.toTypeSignatures(),
additionalValueParameterNamesHash(function),
function.extensionReceiverParameter?.type?.signature
)
@@ -45,6 +43,7 @@ class FunctionApproximationKey(
return false
return name == other.name
&& additionalValueParametersNamesHash == other.additionalValueParametersNamesHash
&& valueParametersTypes.contentEquals(other.valueParametersTypes)
&& extensionReceiverParameterType == other.extensionReceiverParameterType
}
@@ -52,26 +51,39 @@ class FunctionApproximationKey(
override fun hashCode() = hashCode(name)
.appendHashCode(valueParametersTypes)
.appendHashCode(extensionReceiverParameterType)
.appendHashCode(additionalValueParametersNamesHash)
}
/** Used for approximation of [ConstructorDescriptor]s before running concrete [Commonizer]s */
class ConstructorApproximationKey(
private val valueParametersTypes: Array<CirTypeSignature>
private val valueParametersTypes: Array<CirTypeSignature>,
private val additionalValueParametersNamesHash: Int
) {
constructor(constructor: ConstructorDescriptor) : this(
constructor.valueParameters.toTypeSignatures()
constructor.valueParameters.toTypeSignatures(),
additionalValueParameterNamesHash(constructor)
)
override fun equals(other: Any?): Boolean {
if (other !is ConstructorApproximationKey)
return false
return valueParametersTypes.contentEquals(other.valueParametersTypes)
return additionalValueParametersNamesHash == other.additionalValueParametersNamesHash
&& valueParametersTypes.contentEquals(other.valueParametersTypes)
}
override fun hashCode() = hashCode(valueParametersTypes)
.appendHashCode(additionalValueParametersNamesHash)
}
@Suppress("NOTHING_TO_INLINE")
private inline fun List<ValueParameterDescriptor>.toTypeSignatures(): Array<CirTypeSignature> =
Array(size) { index -> this[index].type.signature }
private fun additionalValueParameterNamesHash(callable: FunctionDescriptor): Int {
// TODO: add more precise checks when more languages than C & ObjC are supported
if (callable.annotations.none { it.isObjCInteropCallableAnnotation })
return 0 // do not calculate hash for non-ObjC callables
return callable.valueParameters.fold(0) { acc, next -> acc.appendHashCode(next.name) }
}
@@ -6,6 +6,8 @@
package org.jetbrains.kotlin.descriptors.commonizer.utils
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.serialization.konan.impl.ForwardDeclarationsFqNames
@@ -58,3 +60,10 @@ private fun String.hasPrefix(prefix: String): Boolean {
internal val ClassId.isObjCInteropCallableAnnotation: Boolean
get() = packageFqName.asString() == CINTEROP_PACKAGE && relativeClassName.asString() in OBJC_INTEROP_CALLABLE_ANNOTATIONS
internal val AnnotationDescriptor.isObjCInteropCallableAnnotation: Boolean
get() {
val classifier = type.declarationDescriptor
return classifier.name.asString() in OBJC_INTEROP_CALLABLE_ANNOTATIONS
&& (classifier.containingDeclaration as? PackageFragmentDescriptor)?.fqName?.asString() == CINTEROP_PACKAGE
}