Support fake Java property overrides in function equality in bridges

A synthetic property descriptor created for `B.value` (see the added
test) should not be equal to the normal descriptor created by the fake
override construction algorithm. Otherwise we can't reach this synthetic
non-abstract descriptor when building bridges in `C`, which results in
exception.

 #KT-31367 Fixed
This commit is contained in:
Alexander Udalov
2019-05-24 11:04:16 +02:00
parent d05e72dda8
commit 082c337faa
12 changed files with 100 additions and 13 deletions
@@ -10,6 +10,8 @@ import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor
import org.jetbrains.kotlin.load.java.descriptors.JavaForKotlinOverridePropertyDescriptor
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.jvm.annotations.hasJvmDefaultAnnotation
import org.jetbrains.kotlin.resolve.jvm.annotations.hasPlatformDependentAnnotation
@@ -42,18 +44,27 @@ class DescriptorBasedFunctionHandleForJvm(
override val mightBeIncorrectCode: Boolean
get() = state.classBuilderMode.mightBeIncorrectCode
override fun hashCode(): Int = descriptor.containerEntityForEqualityAndHashCode().hashCode() + 31 * asmMethod.hashCode()
override fun equals(other: Any?): Boolean {
if (other !is DescriptorBasedFunctionHandleForJvm) return false
override fun hashCode(): Int =
(descriptor.containerEntityForEqualityAndHashCode().hashCode() * 31 +
descriptor.isJavaForKotlinOverrideProperty.hashCode()) * 31 +
asmMethod.hashCode()
return asmMethod == other.asmMethod &&
descriptor.containerEntityForEqualityAndHashCode() == other.descriptor.containerEntityForEqualityAndHashCode()
override fun equals(other: Any?): Boolean {
if (this === other) return true
return other is DescriptorBasedFunctionHandleForJvm &&
asmMethod == other.asmMethod &&
descriptor.containerEntityForEqualityAndHashCode() == other.descriptor.containerEntityForEqualityAndHashCode() &&
descriptor.isJavaForKotlinOverrideProperty == other.descriptor.isJavaForKotlinOverrideProperty
}
}
private fun FunctionDescriptor.containerEntityForEqualityAndHashCode(): Any =
(containingDeclaration as? ClassDescriptor)?.typeConstructor ?: containingDeclaration
private val FunctionDescriptor.isJavaForKotlinOverrideProperty: Boolean
get() = this is PropertyAccessorDescriptor && correspondingProperty is JavaForKotlinOverridePropertyDescriptor
private fun CallableMemberDescriptor.isJvmDefaultOrPlatformDependent() =
hasJvmDefaultAnnotation() || hasPlatformDependentAnnotation()