Provide equals/hashCode/toString for KType implementation

This commit is contained in:
Alexander Udalov
2015-08-13 10:13:11 -07:00
parent 9882e86ecb
commit ebe4a8ec89
10 changed files with 144 additions and 8 deletions
@@ -0,0 +1,5 @@
public class J {
public static String foo() {
return "";
}
}
@@ -0,0 +1,11 @@
import kotlin.test.assertNotEquals
fun nonNullString(): String = ""
fun nullableString(): String? = ""
fun box(): String {
assertNotEquals(J::foo.returnType, ::nonNullString.returnType)
assertNotEquals(J::foo.returnType, ::nullableString.returnType)
return "OK"
}
@@ -0,0 +1,11 @@
import java.util.List;
public class J {
public static String string() {
return "";
}
public static List<Object> list() {
return null;
}
}
@@ -0,0 +1,8 @@
import kotlin.test.assertEquals
fun box(): String {
assertEquals("kotlin.String!", J::string.returnType.toString())
assertEquals("kotlin.(Mutable)List<kotlin.Any!>!", J::list.returnType.toString())
return "OK"
}
@@ -0,0 +1,28 @@
import kotlin.reflect.KType
import kotlin.test.assertEquals
import kotlin.test.assertNotEquals
fun unit(p: Unit): Unit {}
fun nullable(s: String): String? = s
class A {
fun <T> typeParam(t: T): T = t
}
fun box(): String {
fun check(t1: KType, t2: KType) {
assertEquals(t1, t2)
assertEquals(t1.hashCode(), t2.hashCode())
}
check(::unit.parameters.single().type, ::unit.returnType)
assertNotEquals(::nullable.parameters.single().type, ::nullable.returnType)
val typeParam = A::class.members.single { it.name == "typeParam" }
check(typeParam.parameters.last().type, typeParam.returnType)
return "OK"
}
@@ -0,0 +1,35 @@
import kotlin.test.assertEquals
fun String?.foo(x: Int, y: Array<Int>, z: IntArray, w: List<Map<Any, A<*>>>) {}
class A<T> {
fun <U> bar(t: T, u: U): T? = null
}
fun baz(inProjection: A<in Number>, outProjection: A<out Number>) {}
fun box(): String {
assertEquals(
listOf(
"kotlin.String?",
"kotlin.Int",
"kotlin.Array<kotlin.Int>",
"kotlin.IntArray",
"kotlin.List<kotlin.Map<kotlin.Any, A<*>>>"
),
String?::foo.parameters.map { it.type.toString() }
)
assertEquals("kotlin.Unit", String?::foo.returnType.toString())
val bar = A::class.members.single { it.name == "bar" }
assertEquals(listOf("A<T>", "T", "U"), bar.parameters.map { it.type.toString() })
assertEquals("T?", bar.returnType.toString())
assertEquals(
listOf("A<in kotlin.Number>", "A<out kotlin.Number>"),
::baz.parameters.map { it.type.toString() }
)
return "OK"
}
@@ -345,6 +345,18 @@ public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodege
doTestWithJava(fileName);
}
@TestMetadata("platformTypeNotEqualToKotlinType")
public void testPlatformTypeNotEqualToKotlinType() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithJava/reflection/platformTypeNotEqualToKotlinType/");
doTestWithJava(fileName);
}
@TestMetadata("platformTypeToString")
public void testPlatformTypeToString() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithJava/reflection/platformTypeToString/");
doTestWithJava(fileName);
}
@TestMetadata("referenceToJavaFieldOfKotlinSubclass")
public void testReferenceToJavaFieldOfKotlinSubclass() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithJava/reflection/referenceToJavaFieldOfKotlinSubclass/");
@@ -3503,6 +3503,18 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/methodsFromAny/propertyToString.kt");
doTestWithStdlib(fileName);
}
@TestMetadata("typeEqualsHashCode.kt")
public void testTypeEqualsHashCode() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/methodsFromAny/typeEqualsHashCode.kt");
doTestWithStdlib(fileName);
}
@TestMetadata("typeToString.kt")
public void testTypeToString() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/methodsFromAny/typeToString.kt");
doTestWithStdlib(fileName);
}
}
@TestMetadata("compiler/testData/codegen/boxWithStdlib/reflection/noKotlinReflect")
@@ -28,4 +28,13 @@ class KTypeImpl(
override val isMarkedNullable: Boolean
get() = type.isMarkedNullable
override fun equals(other: Any?) =
other is KTypeImpl && type.equals(other.type)
override fun hashCode() =
type.hashCode()
override fun toString() =
ReflectionObjectRenderer.renderType(type)
}
@@ -21,20 +21,21 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
import org.jetbrains.kotlin.renderer.DescriptorRenderer
import org.jetbrains.kotlin.types.JetType
object ReflectionObjectRenderer {
private val renderer = DescriptorRenderer.FQ_NAMES_IN_TYPES
private fun StringBuilder.appendReceiverType(receiver: ReceiverParameterDescriptor?) {
if (receiver != null) {
append(renderer.renderType(receiver.getType()))
append(renderType(receiver.type))
append(".")
}
}
private fun StringBuilder.appendReceiversAndName(callable: CallableDescriptor) {
val dispatchReceiver = callable.getDispatchReceiverParameter()
val extensionReceiver = callable.getExtensionReceiverParameter()
val dispatchReceiver = callable.dispatchReceiverParameter
val extensionReceiver = callable.extensionReceiverParameter
appendReceiverType(dispatchReceiver)
@@ -43,13 +44,13 @@ object ReflectionObjectRenderer {
appendReceiverType(extensionReceiver)
if (addParentheses) append(")")
append(renderer.renderName(callable.getName()))
append(renderer.renderName(callable.name))
}
// TODO: include visibility, return type
fun renderProperty(descriptor: PropertyDescriptor): String {
return StringBuilder {
append(if (descriptor.isVar()) "var " else "val ")
append(if (descriptor.isVar) "var " else "val ")
appendReceiversAndName(descriptor)
}.toString()
}
@@ -59,12 +60,16 @@ object ReflectionObjectRenderer {
append("fun ")
appendReceiversAndName(descriptor)
descriptor.getValueParameters().joinTo(this, separator = ", ", prefix = "(", postfix = ")") {
renderer.renderType(it.getType()) // TODO: vararg
descriptor.valueParameters.joinTo(this, separator = ", ", prefix = "(", postfix = ")") {
renderType(it.type) // TODO: vararg
}
append(": ")
append(renderer.renderType(descriptor.getReturnType()!!))
append(renderType(descriptor.returnType!!))
}.toString()
}
fun renderType(type: JetType): String {
return renderer.renderType(type)
}
}