Provide "toString" for reflection objects
This commit is contained in:
@@ -0,0 +1,14 @@
|
|||||||
|
import kotlin.test.*
|
||||||
|
import kotlin.reflect.jvm.kotlin
|
||||||
|
|
||||||
|
class A
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val p = javaClass<A>().kotlin
|
||||||
|
if ("$p" != "class A") return "Fail: $p"
|
||||||
|
|
||||||
|
val s = javaClass<String>().kotlin
|
||||||
|
if ("$s" != "class java.lang.String") return "Fail: $s"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
import kotlin.test.*
|
||||||
|
import kotlin.reflect.jvm.kotlinPackage
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val p = Class.forName("_DefaultPackage").kotlinPackage
|
||||||
|
if ("$p" != "package <default>") return "Fail: $p"
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+66
@@ -0,0 +1,66 @@
|
|||||||
|
import kotlin.reflect.KExtensionProperty
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
fun check(expected: String, p: KExtensionProperty<*, *>) {
|
||||||
|
var s = p.toString()
|
||||||
|
// Strip "val" or "var"
|
||||||
|
s = s.substring(4)
|
||||||
|
// Strip property name, leave only receiver class
|
||||||
|
s = s.substring(0, s.lastIndexOf('.'))
|
||||||
|
|
||||||
|
assertEquals(expected, s)
|
||||||
|
}
|
||||||
|
|
||||||
|
val Boolean.x: Any get() = this
|
||||||
|
val Char.x: Any get() = this
|
||||||
|
val Byte.x: Any get() = this
|
||||||
|
val Short.x: Any get() = this
|
||||||
|
val Int.x: Any get() = this
|
||||||
|
val Float.x: Any get() = this
|
||||||
|
val Long.x: Any get() = this
|
||||||
|
val Double.x: Any get() = this
|
||||||
|
|
||||||
|
val BooleanArray.x: Any get() = this
|
||||||
|
val CharArray.x: Any get() = this
|
||||||
|
val ByteArray.x: Any get() = this
|
||||||
|
val ShortArray.x: Any get() = this
|
||||||
|
val IntArray.x: Any get() = this
|
||||||
|
val FloatArray.x: Any get() = this
|
||||||
|
val LongArray.x: Any get() = this
|
||||||
|
val DoubleArray.x: Any get() = this
|
||||||
|
|
||||||
|
val Array<Int>.a1: Any get() = this
|
||||||
|
val Array<Any>.a2: Any get() = this
|
||||||
|
val Array<Array<String>>.a3: Any get() = this
|
||||||
|
val Array<BooleanArray>.a4: Any get() = this
|
||||||
|
|
||||||
|
val Map<String, Runnable>.m: Any get() = this
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
check("kotlin.Boolean", Boolean::x)
|
||||||
|
check("kotlin.Char", Char::x)
|
||||||
|
check("kotlin.Byte", Byte::x)
|
||||||
|
check("kotlin.Short", Short::x)
|
||||||
|
check("kotlin.Int", Int::x)
|
||||||
|
check("kotlin.Float", Float::x)
|
||||||
|
check("kotlin.Long", Long::x)
|
||||||
|
check("kotlin.Double", Double::x)
|
||||||
|
|
||||||
|
check("kotlin.BooleanArray", BooleanArray::x)
|
||||||
|
check("kotlin.CharArray", CharArray::x)
|
||||||
|
check("kotlin.ByteArray", ByteArray::x)
|
||||||
|
check("kotlin.ShortArray", ShortArray::x)
|
||||||
|
check("kotlin.IntArray", IntArray::x)
|
||||||
|
check("kotlin.FloatArray", FloatArray::x)
|
||||||
|
check("kotlin.LongArray", LongArray::x)
|
||||||
|
check("kotlin.DoubleArray", DoubleArray::x)
|
||||||
|
|
||||||
|
check("kotlin.Array<java.lang.Integer>", Array<Int>::a1)
|
||||||
|
check("kotlin.Array<java.lang.Object>", Array<Any>::a2)
|
||||||
|
check("kotlin.Array<kotlin.Array<java.lang.String>>", Array<Array<String>>::a3)
|
||||||
|
check("kotlin.Array<kotlin.BooleanArray>", Array<BooleanArray>::a4)
|
||||||
|
|
||||||
|
check("java.util.Map", Map<String, Runnable>::m)
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
import kotlin.test.*
|
||||||
|
import kotlin.reflect.jvm.kotlinPackage
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val p = javaClass<String>().kotlinPackage
|
||||||
|
if ("$p" != "package java.lang.String") return "Fail: $p"
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package test.foo.bar
|
||||||
|
|
||||||
|
import kotlin.test.*
|
||||||
|
import kotlin.reflect.jvm.kotlinPackage
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val p = Class.forName("test.foo.bar.BarPackage").kotlinPackage
|
||||||
|
if ("$p" != "package test.foo.bar") return "Fail: $p"
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
val top = 42
|
||||||
|
var top2 = -23
|
||||||
|
|
||||||
|
val String.ext: Int get() = 0
|
||||||
|
var IntRange?.ext2: Int get() = 0; set(value) {}
|
||||||
|
|
||||||
|
class A(val mem: String)
|
||||||
|
class B(var mem: String)
|
||||||
|
|
||||||
|
fun assertToString(s: String, x: Any) {
|
||||||
|
assertEquals(s, x.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
assertToString("val top", ::top)
|
||||||
|
assertToString("var top2", ::top2)
|
||||||
|
assertToString("val java.lang.String.ext", String::ext)
|
||||||
|
assertToString("var kotlin.IntRange.ext2", IntRange::ext2)
|
||||||
|
assertToString("val test.A.mem", A::mem)
|
||||||
|
assertToString("var test.B.mem", B::mem)
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+30
@@ -1536,11 +1536,41 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
|
|||||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/codegen/boxWithStdlib/reflection/methodsFromAny"), Pattern.compile("^(.+)\\.kt$"), true);
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/codegen/boxWithStdlib/reflection/methodsFromAny"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("classToString.kt")
|
||||||
|
public void testClassToString() throws Exception {
|
||||||
|
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/methodsFromAny/classToString.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("defaultPackageToString.kt")
|
||||||
|
public void testDefaultPackageToString() throws Exception {
|
||||||
|
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/methodsFromAny/defaultPackageToString.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("equalsHashCode.kt")
|
@TestMetadata("equalsHashCode.kt")
|
||||||
public void testEqualsHashCode() throws Exception {
|
public void testEqualsHashCode() throws Exception {
|
||||||
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/methodsFromAny/equalsHashCode.kt");
|
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/methodsFromAny/equalsHashCode.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("extensionPropertyReceiverToString.kt")
|
||||||
|
public void testExtensionPropertyReceiverToString() throws Exception {
|
||||||
|
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/methodsFromAny/extensionPropertyReceiverToString.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("packageForJavaStaticToString.kt")
|
||||||
|
public void testPackageForJavaStaticToString() throws Exception {
|
||||||
|
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/methodsFromAny/packageForJavaStaticToString.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("packageToString.kt")
|
||||||
|
public void testPackageToString() throws Exception {
|
||||||
|
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/methodsFromAny/packageToString.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("propertyToString.kt")
|
||||||
|
public void testPropertyToString() throws Exception {
|
||||||
|
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/methodsFromAny/propertyToString.kt");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Test innerSuite() {
|
public static Test innerSuite() {
|
||||||
|
|||||||
@@ -62,4 +62,7 @@ class KClassImpl<out T>(val jClass: Class<T>) : KClass<T> {
|
|||||||
|
|
||||||
override fun hashCode(): Int =
|
override fun hashCode(): Int =
|
||||||
jClass.hashCode()
|
jClass.hashCode()
|
||||||
|
|
||||||
|
override fun toString(): String =
|
||||||
|
jClass.toString()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,10 @@ open class KForeignMemberProperty<T : Any, out R>(
|
|||||||
|
|
||||||
override fun hashCode(): Int =
|
override fun hashCode(): Int =
|
||||||
name.hashCode() * 31 + owner.hashCode()
|
name.hashCode() * 31 + owner.hashCode()
|
||||||
|
|
||||||
|
// TODO: include visibility, return type
|
||||||
|
override fun toString(): String =
|
||||||
|
"val ${owner.jClass.getName()}.$name"
|
||||||
}
|
}
|
||||||
|
|
||||||
class KMutableForeignMemberProperty<T : Any, out R>(
|
class KMutableForeignMemberProperty<T : Any, out R>(
|
||||||
@@ -47,4 +51,7 @@ class KMutableForeignMemberProperty<T : Any, out R>(
|
|||||||
override fun set(receiver: T, value: R) {
|
override fun set(receiver: T, value: R) {
|
||||||
field.set(receiver, value)
|
field.set(receiver, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun toString(): String =
|
||||||
|
"var ${owner.jClass.getName()}.$name"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,10 @@ open class KMemberPropertyImpl<T : Any, out R>(
|
|||||||
|
|
||||||
override fun hashCode(): Int =
|
override fun hashCode(): Int =
|
||||||
name.hashCode() * 31 + owner.hashCode()
|
name.hashCode() * 31 + owner.hashCode()
|
||||||
|
|
||||||
|
// TODO: include visibility, return type
|
||||||
|
override fun toString(): String =
|
||||||
|
"val ${owner.jClass.getName()}.$name"
|
||||||
}
|
}
|
||||||
|
|
||||||
class KMutableMemberPropertyImpl<T : Any, R>(
|
class KMutableMemberPropertyImpl<T : Any, R>(
|
||||||
@@ -56,4 +60,7 @@ class KMutableMemberPropertyImpl<T : Any, R>(
|
|||||||
override fun set(receiver: T, value: R) {
|
override fun set(receiver: T, value: R) {
|
||||||
setter(receiver, value)
|
setter(receiver, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun toString(): String =
|
||||||
|
"var ${owner.jClass.getName()}.$name"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,9 @@
|
|||||||
package kotlin.reflect.jvm.internal
|
package kotlin.reflect.jvm.internal
|
||||||
|
|
||||||
import kotlin.reflect.KPackage
|
import kotlin.reflect.KPackage
|
||||||
|
import kotlin.jvm.internal.KotlinPackage
|
||||||
|
|
||||||
|
private val KOTLIN_PACKAGE_ANNOTATION_CLASS = javaClass<KotlinPackage>()
|
||||||
|
|
||||||
class KPackageImpl(val jClass: Class<*>) : KPackage {
|
class KPackageImpl(val jClass: Class<*>) : KPackage {
|
||||||
override fun equals(other: Any?): Boolean =
|
override fun equals(other: Any?): Boolean =
|
||||||
@@ -24,4 +27,23 @@ class KPackageImpl(val jClass: Class<*>) : KPackage {
|
|||||||
|
|
||||||
override fun hashCode(): Int =
|
override fun hashCode(): Int =
|
||||||
jClass.hashCode()
|
jClass.hashCode()
|
||||||
|
|
||||||
|
suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN")
|
||||||
|
override fun toString(): String {
|
||||||
|
val name = jClass.getName() as java.lang.String
|
||||||
|
return if (jClass.isAnnotationPresent(KOTLIN_PACKAGE_ANNOTATION_CLASS)) {
|
||||||
|
// Cast to Any is needed to suppress the error: "Operator '==' cannot be applied to 'java.lang.String' and 'kotlin.String'"
|
||||||
|
if ((name : Any) == "_DefaultPackage") {
|
||||||
|
"package <default>"
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
val lastDot = name.lastIndexOf(".")
|
||||||
|
if (lastDot >= 0) {
|
||||||
|
"package ${name.substring(0, lastDot)}"
|
||||||
|
}
|
||||||
|
else "package $name"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else "package $name"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,10 @@ open class KTopLevelExtensionPropertyImpl<T, out R>(
|
|||||||
|
|
||||||
override fun hashCode(): Int =
|
override fun hashCode(): Int =
|
||||||
(name.hashCode() * 31 + owner.hashCode()) * 31 + receiverClass.hashCode()
|
(name.hashCode() * 31 + owner.hashCode()) * 31 + receiverClass.hashCode()
|
||||||
|
|
||||||
|
// TODO: include visibility, return type, maybe package
|
||||||
|
override fun toString(): String =
|
||||||
|
"val ${mapJavaClassToKotlin(receiverClass.getName())}.$name"
|
||||||
}
|
}
|
||||||
|
|
||||||
class KMutableTopLevelExtensionPropertyImpl<T, R>(
|
class KMutableTopLevelExtensionPropertyImpl<T, R>(
|
||||||
@@ -50,4 +54,40 @@ class KMutableTopLevelExtensionPropertyImpl<T, R>(
|
|||||||
override fun set(receiver: T, value: R) {
|
override fun set(receiver: T, value: R) {
|
||||||
setter.invoke(null, receiver, value)
|
setter.invoke(null, receiver, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun toString(): String =
|
||||||
|
"var ${mapJavaClassToKotlin(receiverClass.getName())}.$name"
|
||||||
|
}
|
||||||
|
|
||||||
|
suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN")
|
||||||
|
private fun mapJavaClassToKotlin(name: String): String {
|
||||||
|
if (Character.isLowerCase(name[0])) {
|
||||||
|
return when (name) {
|
||||||
|
"boolean" -> "kotlin.Boolean"
|
||||||
|
"char" -> "kotlin.Char"
|
||||||
|
"byte" -> "kotlin.Byte"
|
||||||
|
"short" -> "kotlin.Short"
|
||||||
|
"int" -> "kotlin.Int"
|
||||||
|
"float" -> "kotlin.Float"
|
||||||
|
"long" -> "kotlin.Long"
|
||||||
|
"double" -> "kotlin.Double"
|
||||||
|
else -> name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (name[0] == '[') {
|
||||||
|
val element = (name as java.lang.String).substring(1)
|
||||||
|
return when (element[0]) {
|
||||||
|
'Z' -> "kotlin.BooleanArray"
|
||||||
|
'C' -> "kotlin.CharArray"
|
||||||
|
'B' -> "kotlin.ByteArray"
|
||||||
|
'S' -> "kotlin.ShortArray"
|
||||||
|
'I' -> "kotlin.IntArray"
|
||||||
|
'F' -> "kotlin.FloatArray"
|
||||||
|
'J' -> "kotlin.LongArray"
|
||||||
|
'D' -> "kotlin.DoubleArray"
|
||||||
|
'L' -> "kotlin.Array<${mapJavaClassToKotlin((element as java.lang.String).substring(1, element.length() - 1))}>"
|
||||||
|
else -> "kotlin.Array<${mapJavaClassToKotlin(element)}>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return name
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,10 @@ open class KTopLevelVariableImpl<out R>(
|
|||||||
|
|
||||||
override fun hashCode(): Int =
|
override fun hashCode(): Int =
|
||||||
name.hashCode() * 31 + owner.hashCode()
|
name.hashCode() * 31 + owner.hashCode()
|
||||||
|
|
||||||
|
// TODO: include visibility, return type, maybe package
|
||||||
|
override fun toString(): String =
|
||||||
|
"val $name"
|
||||||
}
|
}
|
||||||
|
|
||||||
class KMutableTopLevelVariableImpl<R>(
|
class KMutableTopLevelVariableImpl<R>(
|
||||||
@@ -49,4 +53,7 @@ class KMutableTopLevelVariableImpl<R>(
|
|||||||
override fun set(value: R) {
|
override fun set(value: R) {
|
||||||
setter.invoke(null, value)
|
setter.invoke(null, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun toString(): String =
|
||||||
|
"var $name"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user