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);
|
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")
|
@TestMetadata("propertyEqualsHashCode.kt")
|
||||||
public void testPropertyEqualsHashCode() throws Exception {
|
public void testPropertyEqualsHashCode() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/methodsFromAny/propertyEqualsHashCode.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/methodsFromAny/propertyEqualsHashCode.kt");
|
||||||
|
|||||||
@@ -41,4 +41,13 @@ class KParameterImpl(
|
|||||||
|
|
||||||
override val type: KType
|
override val type: KType
|
||||||
get() = KTypeImpl(descriptor.type) { callable.caller.parameterTypes[index] }
|
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.descriptors.ReceiverParameterDescriptor
|
||||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||||
import org.jetbrains.kotlin.types.JetType
|
import org.jetbrains.kotlin.types.JetType
|
||||||
|
import kotlin.reflect.KParameter
|
||||||
|
|
||||||
object ReflectionObjectRenderer {
|
object ReflectionObjectRenderer {
|
||||||
private val renderer = DescriptorRenderer.FQ_NAMES_IN_TYPES
|
private val renderer = DescriptorRenderer.FQ_NAMES_IN_TYPES
|
||||||
@@ -47,6 +48,14 @@ object ReflectionObjectRenderer {
|
|||||||
append(renderer.renderName(callable.name))
|
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
|
// TODO: include visibility, return type
|
||||||
fun renderProperty(descriptor: PropertyDescriptor): String {
|
fun renderProperty(descriptor: PropertyDescriptor): String {
|
||||||
return StringBuilder {
|
return StringBuilder {
|
||||||
@@ -69,6 +78,19 @@ object ReflectionObjectRenderer {
|
|||||||
}.toString()
|
}.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 {
|
fun renderType(type: JetType): String {
|
||||||
return renderer.renderType(type)
|
return renderer.renderType(type)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user