Do not rely on descriptors in KParameterImpl.equals/hashCode
For the same reason as in the previous commit: descriptors are cached via weak references in moduleByClassLoader.kt and can be garbage-collected at any point. So different instances of KParameterImpl representing the same parameter may store different instances of descriptors.
This commit is contained in:
Generated
+5
@@ -26167,6 +26167,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
|||||||
runTest("compiler/testData/codegen/box/reflection/methodsFromAny/parametersEqualsHashCode.kt");
|
runTest("compiler/testData/codegen/box/reflection/methodsFromAny/parametersEqualsHashCode.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("parametersEqualsWithClearCaches.kt")
|
||||||
|
public void testParametersEqualsWithClearCaches() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/methodsFromAny/parametersEqualsWithClearCaches.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("parametersToString.kt")
|
@TestMetadata("parametersToString.kt")
|
||||||
public void testParametersToString() throws Exception {
|
public void testParametersToString() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/reflection/methodsFromAny/parametersToString.kt");
|
runTest("compiler/testData/codegen/box/reflection/methodsFromAny/parametersToString.kt");
|
||||||
|
|||||||
+46
@@ -0,0 +1,46 @@
|
|||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// WITH_REFLECT
|
||||||
|
// FILE: box.kt
|
||||||
|
|
||||||
|
import kotlin.reflect.KMutableProperty
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
inline fun check(message: String, generate: () -> Any?) {
|
||||||
|
val x1: Any?
|
||||||
|
val x2: Any?
|
||||||
|
try {
|
||||||
|
x1 = generate()
|
||||||
|
|
||||||
|
// Force clear the internal maps, as if the weak values in them are garbage-collected.
|
||||||
|
kotlin.reflect.jvm.internal.ReflectionFactoryImpl.clearCaches()
|
||||||
|
|
||||||
|
x2 = generate()
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
throw AssertionError("Fail $message", e)
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals(x1, x2, "Fail equals $message")
|
||||||
|
assertEquals(x2, x1, "Fail equals $message")
|
||||||
|
assertEquals(x1.hashCode(), x2.hashCode(), "Fail hashCode $message")
|
||||||
|
}
|
||||||
|
|
||||||
|
class C(c: Any) {
|
||||||
|
fun Any.a(a: Any): Any = a
|
||||||
|
|
||||||
|
var <X> X.x: X
|
||||||
|
get() = this
|
||||||
|
set(value) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
check("constructor parameter") { C::class.constructors.single().parameters.single() }
|
||||||
|
check("instance parameter") { C::class.members.single { it.name == "a" }.parameters[0] }
|
||||||
|
check("value parameter") { C::class.members.single { it.name == "a" }.parameters[1] }
|
||||||
|
|
||||||
|
check("extension receiver parameter") { (C::class.members.single { it.name == "x" } as KMutableProperty<*>).parameters[1] }
|
||||||
|
|
||||||
|
// TODO: depends on KT-13490
|
||||||
|
// check("property setter parameter") { (C::class.members.single { it.name == "x" } as KMutableProperty<*>).setter.parameters[2] }
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+5
@@ -27753,6 +27753,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
runTest("compiler/testData/codegen/box/reflection/methodsFromAny/parametersEqualsHashCode.kt");
|
runTest("compiler/testData/codegen/box/reflection/methodsFromAny/parametersEqualsHashCode.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("parametersEqualsWithClearCaches.kt")
|
||||||
|
public void testParametersEqualsWithClearCaches() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/methodsFromAny/parametersEqualsWithClearCaches.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("parametersToString.kt")
|
@TestMetadata("parametersToString.kt")
|
||||||
public void testParametersToString() throws Exception {
|
public void testParametersToString() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/reflection/methodsFromAny/parametersToString.kt");
|
runTest("compiler/testData/codegen/box/reflection/methodsFromAny/parametersToString.kt");
|
||||||
|
|||||||
+5
@@ -25387,6 +25387,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/reflection/methodsFromAny/parametersEqualsHashCode.kt");
|
runTest("compiler/testData/codegen/box/reflection/methodsFromAny/parametersEqualsHashCode.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("parametersEqualsWithClearCaches.kt")
|
||||||
|
public void testParametersEqualsWithClearCaches() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/methodsFromAny/parametersEqualsWithClearCaches.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("parametersToString.kt")
|
@TestMetadata("parametersToString.kt")
|
||||||
public void testParametersToString() throws Exception {
|
public void testParametersToString() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/reflection/methodsFromAny/parametersToString.kt");
|
runTest("compiler/testData/codegen/box/reflection/methodsFromAny/parametersToString.kt");
|
||||||
|
|||||||
+5
@@ -26167,6 +26167,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/reflection/methodsFromAny/parametersEqualsHashCode.kt");
|
runTest("compiler/testData/codegen/box/reflection/methodsFromAny/parametersEqualsHashCode.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("parametersEqualsWithClearCaches.kt")
|
||||||
|
public void testParametersEqualsWithClearCaches() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/methodsFromAny/parametersEqualsWithClearCaches.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("parametersToString.kt")
|
@TestMetadata("parametersToString.kt")
|
||||||
public void testParametersToString() throws Exception {
|
public void testParametersToString() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/reflection/methodsFromAny/parametersToString.kt");
|
runTest("compiler/testData/codegen/box/reflection/methodsFromAny/parametersToString.kt");
|
||||||
|
|||||||
@@ -64,10 +64,10 @@ internal class KParameterImpl(
|
|||||||
get() = descriptor.let { it is ValueParameterDescriptor && it.varargElementType != null }
|
get() = descriptor.let { it is ValueParameterDescriptor && it.varargElementType != null }
|
||||||
|
|
||||||
override fun equals(other: Any?) =
|
override fun equals(other: Any?) =
|
||||||
other is KParameterImpl && callable == other.callable && descriptor == other.descriptor
|
other is KParameterImpl && callable == other.callable && index == other.index
|
||||||
|
|
||||||
override fun hashCode() =
|
override fun hashCode() =
|
||||||
(callable.hashCode() * 31) + descriptor.hashCode()
|
(callable.hashCode() * 31) + index.hashCode()
|
||||||
|
|
||||||
override fun toString() =
|
override fun toString() =
|
||||||
ReflectionObjectRenderer.renderParameter(this)
|
ReflectionObjectRenderer.renderParameter(this)
|
||||||
|
|||||||
Reference in New Issue
Block a user