K/N: Use class FQN in default toString() implementation
^KT-47167
This commit is contained in:
@@ -816,6 +816,10 @@ task tostring3(type: KonanLocalTest) {
|
|||||||
source = "runtime/basic/tostring3.kt"
|
source = "runtime/basic/tostring3.kt"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
task tostring4(type: KonanLocalTest) {
|
||||||
|
source = "runtime/basic/tostring4.kt"
|
||||||
|
}
|
||||||
|
|
||||||
task empty_substring(type: KonanLocalTest) {
|
task empty_substring(type: KonanLocalTest) {
|
||||||
goldValue = "\n"
|
goldValue = "\n"
|
||||||
source = "runtime/basic/empty_substring.kt"
|
source = "runtime/basic/empty_substring.kt"
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package runtime.basic.tostring4
|
||||||
|
|
||||||
|
import kotlin.test.*
|
||||||
|
|
||||||
|
class TopLevel
|
||||||
|
|
||||||
|
@Test fun runTest() {
|
||||||
|
assertEquals("runtime.basic.tostring4.TopLevel", TopLevel().toStringWithoutHashCode())
|
||||||
|
|
||||||
|
class Local1
|
||||||
|
assertEquals("runtime.basic.tostring4.runTest\$Local1", Local1().toStringWithoutHashCode())
|
||||||
|
|
||||||
|
assertEquals("runtime.basic.tostring4.runTest\$1", object {}.toStringWithoutHashCode())
|
||||||
|
|
||||||
|
fun localFun() {
|
||||||
|
class Local2
|
||||||
|
assertEquals("runtime.basic.tostring4.runTest\$localFun\$Local2", Local2().toStringWithoutHashCode())
|
||||||
|
|
||||||
|
assertEquals("runtime.basic.tostring4.runTest\$localFun\$1", object {}.toStringWithoutHashCode())
|
||||||
|
}
|
||||||
|
localFun()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Any.toStringWithoutHashCode(): String {
|
||||||
|
val string = toString()
|
||||||
|
assertEquals(1, string.count { it == '@' }, "Invalid toString() value: $string")
|
||||||
|
return string.substringBefore('@')
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
package kotlin
|
package kotlin
|
||||||
|
|
||||||
import kotlin.native.identityHashCode
|
import kotlin.native.identityHashCode
|
||||||
|
import kotlin.native.internal.fullName
|
||||||
import kotlin.native.internal.ExportTypeInfo
|
import kotlin.native.internal.ExportTypeInfo
|
||||||
import kotlin.native.internal.GCUnsafeCall
|
import kotlin.native.internal.GCUnsafeCall
|
||||||
|
|
||||||
@@ -41,8 +42,7 @@ public open class Any {
|
|||||||
* Returns a string representation of the object.
|
* Returns a string representation of the object.
|
||||||
*/
|
*/
|
||||||
public open fun toString(): String {
|
public open fun toString(): String {
|
||||||
val kClass = this::class
|
val className = this::class.fullName ?: "<object>"
|
||||||
val className = kClass.qualifiedName ?: kClass.simpleName ?: "<object>"
|
|
||||||
// TODO: consider using [identityHashCode].
|
// TODO: consider using [identityHashCode].
|
||||||
val unsignedHashCode = this.hashCode().toLong() and 0xffffffffL
|
val unsignedHashCode = this.hashCode().toLong() and 0xffffffffL
|
||||||
val hashCodeStr = unsignedHashCode.toString(16)
|
val hashCodeStr = unsignedHashCode.toString(16)
|
||||||
|
|||||||
@@ -27,20 +27,22 @@ internal class KClassImpl<T : Any>(private val typeInfo: NativePtr) : KClass<T>
|
|||||||
|
|
||||||
override fun hashCode(): Int = typeInfo.hashCode()
|
override fun hashCode(): Int = typeInfo.hashCode()
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String = "class ${fullName ?: "<anonymous>"}"
|
||||||
val relativeName = getRelativeName(typeInfo, false)
|
|
||||||
val visibleName = if (relativeName != null) {
|
|
||||||
val packageName = getPackageName(typeInfo, false)!!
|
|
||||||
if (packageName.isEmpty()) relativeName else "$packageName.$relativeName"
|
|
||||||
} else "<anonymous>"
|
|
||||||
|
|
||||||
return "class $visibleName"
|
internal val fullName: String?
|
||||||
}
|
get() {
|
||||||
|
val relativeName = getRelativeName(typeInfo, false) ?: return null
|
||||||
|
val packageName = getPackageName(typeInfo, false)!!
|
||||||
|
return if (packageName.isEmpty()) relativeName else "$packageName.$relativeName"
|
||||||
|
}
|
||||||
|
|
||||||
internal fun findAssociatedObjectImpl(key: KClassImpl<*>): Any? =
|
internal fun findAssociatedObjectImpl(key: KClassImpl<*>): Any? =
|
||||||
findAssociatedObjectImpl(this.typeInfo, key.typeInfo)
|
findAssociatedObjectImpl(this.typeInfo, key.typeInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal val KClass<*>.fullName: String?
|
||||||
|
get() = (this as? KClassImpl<*>)?.fullName
|
||||||
|
|
||||||
@PublishedApi
|
@PublishedApi
|
||||||
internal fun KClass<*>.findAssociatedObject(key: KClass<*>): Any? =
|
internal fun KClass<*>.findAssociatedObject(key: KClass<*>): Any? =
|
||||||
if (this is KClassImpl<*> && key is KClassImpl<*>) {
|
if (this is KClassImpl<*> && key is KClassImpl<*>) {
|
||||||
|
|||||||
Reference in New Issue
Block a user