Provide equals/hashCode/toString for KType implementation
This commit is contained in:
+5
@@ -0,0 +1,5 @@
|
|||||||
|
public class J {
|
||||||
|
public static String foo() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
+11
@@ -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"
|
||||||
|
}
|
||||||
+28
@@ -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"
|
||||||
|
}
|
||||||
+35
@@ -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"
|
||||||
|
}
|
||||||
+12
@@ -345,6 +345,18 @@ public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodege
|
|||||||
doTestWithJava(fileName);
|
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")
|
@TestMetadata("referenceToJavaFieldOfKotlinSubclass")
|
||||||
public void testReferenceToJavaFieldOfKotlinSubclass() throws Exception {
|
public void testReferenceToJavaFieldOfKotlinSubclass() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithJava/reflection/referenceToJavaFieldOfKotlinSubclass/");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithJava/reflection/referenceToJavaFieldOfKotlinSubclass/");
|
||||||
|
|||||||
+12
@@ -3503,6 +3503,18 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
|
|||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/methodsFromAny/propertyToString.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/methodsFromAny/propertyToString.kt");
|
||||||
doTestWithStdlib(fileName);
|
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")
|
@TestMetadata("compiler/testData/codegen/boxWithStdlib/reflection/noKotlinReflect")
|
||||||
|
|||||||
@@ -28,4 +28,13 @@ class KTypeImpl(
|
|||||||
|
|
||||||
override val isMarkedNullable: Boolean
|
override val isMarkedNullable: Boolean
|
||||||
get() = type.isMarkedNullable
|
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.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
|
||||||
|
|
||||||
object ReflectionObjectRenderer {
|
object ReflectionObjectRenderer {
|
||||||
private val renderer = DescriptorRenderer.FQ_NAMES_IN_TYPES
|
private val renderer = DescriptorRenderer.FQ_NAMES_IN_TYPES
|
||||||
|
|
||||||
private fun StringBuilder.appendReceiverType(receiver: ReceiverParameterDescriptor?) {
|
private fun StringBuilder.appendReceiverType(receiver: ReceiverParameterDescriptor?) {
|
||||||
if (receiver != null) {
|
if (receiver != null) {
|
||||||
append(renderer.renderType(receiver.getType()))
|
append(renderType(receiver.type))
|
||||||
append(".")
|
append(".")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun StringBuilder.appendReceiversAndName(callable: CallableDescriptor) {
|
private fun StringBuilder.appendReceiversAndName(callable: CallableDescriptor) {
|
||||||
val dispatchReceiver = callable.getDispatchReceiverParameter()
|
val dispatchReceiver = callable.dispatchReceiverParameter
|
||||||
val extensionReceiver = callable.getExtensionReceiverParameter()
|
val extensionReceiver = callable.extensionReceiverParameter
|
||||||
|
|
||||||
appendReceiverType(dispatchReceiver)
|
appendReceiverType(dispatchReceiver)
|
||||||
|
|
||||||
@@ -43,13 +44,13 @@ object ReflectionObjectRenderer {
|
|||||||
appendReceiverType(extensionReceiver)
|
appendReceiverType(extensionReceiver)
|
||||||
if (addParentheses) append(")")
|
if (addParentheses) append(")")
|
||||||
|
|
||||||
append(renderer.renderName(callable.getName()))
|
append(renderer.renderName(callable.name))
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: include visibility, return type
|
// TODO: include visibility, return type
|
||||||
fun renderProperty(descriptor: PropertyDescriptor): String {
|
fun renderProperty(descriptor: PropertyDescriptor): String {
|
||||||
return StringBuilder {
|
return StringBuilder {
|
||||||
append(if (descriptor.isVar()) "var " else "val ")
|
append(if (descriptor.isVar) "var " else "val ")
|
||||||
appendReceiversAndName(descriptor)
|
appendReceiversAndName(descriptor)
|
||||||
}.toString()
|
}.toString()
|
||||||
}
|
}
|
||||||
@@ -59,12 +60,16 @@ object ReflectionObjectRenderer {
|
|||||||
append("fun ")
|
append("fun ")
|
||||||
appendReceiversAndName(descriptor)
|
appendReceiversAndName(descriptor)
|
||||||
|
|
||||||
descriptor.getValueParameters().joinTo(this, separator = ", ", prefix = "(", postfix = ")") {
|
descriptor.valueParameters.joinTo(this, separator = ", ", prefix = "(", postfix = ")") {
|
||||||
renderer.renderType(it.getType()) // TODO: vararg
|
renderType(it.type) // TODO: vararg
|
||||||
}
|
}
|
||||||
|
|
||||||
append(": ")
|
append(": ")
|
||||||
append(renderer.renderType(descriptor.getReturnType()!!))
|
append(renderType(descriptor.returnType!!))
|
||||||
}.toString()
|
}.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun renderType(type: JetType): String {
|
||||||
|
return renderer.renderType(type)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user