Provide equals/hashCode/toString for KParameter implementation
Two KParameter instances are equal iff their backing descriptors are equal and their callables are equal
This commit is contained in:
Vendored
+26
@@ -0,0 +1,26 @@
|
||||
import kotlin.test.*
|
||||
|
||||
class A {
|
||||
fun foo(s: String, x: Int) {}
|
||||
fun bar(x: Int) {}
|
||||
val baz = 42
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
// Dispatch receiver parameters of different callables are not equal
|
||||
assertNotEquals(A::foo.parameters[0], A::bar.parameters[0])
|
||||
assertNotEquals(A::foo.parameters[0], A::baz.parameters[0])
|
||||
|
||||
assertNotEquals(A::foo.parameters[1], A::bar.parameters[1])
|
||||
assertNotEquals(A::foo.parameters[1], A::foo.parameters[2])
|
||||
assertNotEquals(A::bar.parameters[1], A::foo.parameters[2])
|
||||
|
||||
assertEquals(A::foo.parameters[0], A::foo.parameters[0])
|
||||
assertEquals(A::foo.parameters[0].hashCode(), A::foo.parameters[0].hashCode())
|
||||
assertEquals(A::foo.parameters[1], A::foo.parameters[1])
|
||||
assertEquals(A::foo.parameters[1].hashCode(), A::foo.parameters[1].hashCode())
|
||||
assertEquals(A::bar.parameters[0], A::bar.parameters[0])
|
||||
assertEquals(A::bar.parameters[0].hashCode(), A::bar.parameters[0].hashCode())
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
import kotlin.test.*
|
||||
|
||||
fun Int.foo(s: String) {}
|
||||
|
||||
class A {
|
||||
fun bar() {}
|
||||
}
|
||||
|
||||
fun baz(name: String) {}
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(
|
||||
listOf("extension receiver of ${Int::foo}", "parameter #1 s of ${Int::foo}"),
|
||||
Int::foo.parameters.map(Any::toString)
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
listOf("instance of ${A::bar}"),
|
||||
A::bar.parameters.map(Any::toString)
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
listOf("parameter #0 name of ${::baz}"),
|
||||
::baz.parameters.map(Any::toString)
|
||||
)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+12
@@ -3492,6 +3492,18 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("parametersEqualsHashCode.kt")
|
||||
public void testParametersEqualsHashCode() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/methodsFromAny/parametersEqualsHashCode.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("parametersToString.kt")
|
||||
public void testParametersToString() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/methodsFromAny/parametersToString.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("propertyEqualsHashCode.kt")
|
||||
public void testPropertyEqualsHashCode() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/methodsFromAny/propertyEqualsHashCode.kt");
|
||||
|
||||
@@ -41,4 +41,13 @@ class KParameterImpl(
|
||||
|
||||
override val type: KType
|
||||
get() = KTypeImpl(descriptor.type) { callable.caller.parameterTypes[index] }
|
||||
|
||||
override fun equals(other: Any?) =
|
||||
other is KParameterImpl && callable == other.callable && descriptor == other.descriptor
|
||||
|
||||
override fun hashCode() =
|
||||
(callable.hashCode() * 31) + descriptor.hashCode()
|
||||
|
||||
override fun toString() =
|
||||
ReflectionObjectRenderer.renderParameter(this)
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||
import org.jetbrains.kotlin.types.JetType
|
||||
import kotlin.reflect.KParameter
|
||||
|
||||
object ReflectionObjectRenderer {
|
||||
private val renderer = DescriptorRenderer.FQ_NAMES_IN_TYPES
|
||||
@@ -47,6 +48,14 @@ object ReflectionObjectRenderer {
|
||||
append(renderer.renderName(callable.name))
|
||||
}
|
||||
|
||||
fun renderCallable(descriptor: CallableDescriptor): String {
|
||||
return when (descriptor) {
|
||||
is PropertyDescriptor -> renderProperty(descriptor)
|
||||
is FunctionDescriptor -> renderFunction(descriptor)
|
||||
else -> error("Illegal callable: $descriptor")
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: include visibility, return type
|
||||
fun renderProperty(descriptor: PropertyDescriptor): String {
|
||||
return StringBuilder {
|
||||
@@ -69,6 +78,19 @@ object ReflectionObjectRenderer {
|
||||
}.toString()
|
||||
}
|
||||
|
||||
fun renderParameter(parameter: KParameterImpl): String {
|
||||
return StringBuilder {
|
||||
when (parameter.kind) {
|
||||
KParameter.Kind.EXTENSION_RECEIVER -> append("extension receiver")
|
||||
KParameter.Kind.INSTANCE -> append("instance")
|
||||
KParameter.Kind.VALUE -> append("parameter #${parameter.index} ${parameter.name}")
|
||||
}
|
||||
|
||||
append(" of ")
|
||||
append(renderCallable(parameter.callable.descriptor))
|
||||
}.toString()
|
||||
}
|
||||
|
||||
fun renderType(type: JetType): String {
|
||||
return renderer.renderType(type)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user