Fix KClass.simpleName for local classes

This commit is contained in:
Alexander Udalov
2015-03-18 17:14:13 +03:00
parent aaef2d42cd
commit 9cf0720925
3 changed files with 66 additions and 3 deletions
@@ -0,0 +1,39 @@
import kotlin.reflect.KClass
import kotlin.test.assertEquals
fun check(klass: KClass<*>, expectedName: String) {
assertEquals(expectedName, klass.simpleName)
}
fun localInMethod() {
fun localInMethod(unused: Any?) {
class Local
check(Local::class, "Local")
class `Local$With$Dollars`
check(`Local$With$Dollars`::class, "Local\$With\$Dollars")
}
localInMethod(null)
class Local
check(Local::class, "Local")
class `Local$With$Dollars`
check(`Local$With$Dollars`::class, "Local\$With\$Dollars")
}
class LocalInConstructor {
init {
class Local
check(Local::class, "Local")
class `Local$With$Dollars`
check(`Local$With$Dollars`::class, "Local\$With\$Dollars")
}
}
fun box(): String {
localInMethod()
LocalInConstructor()
return "OK"
}
@@ -2563,6 +2563,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
doTestWithStdlib(fileName);
}
@TestMetadata("localClassSimpleName.kt")
public void testLocalClassSimpleName() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/classLiterals/localClassSimpleName.kt");
doTestWithStdlib(fileName);
}
@TestMetadata("simpleClassLiteral.kt")
public void testSimpleClassLiteral() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/classLiterals/simpleClassLiteral.kt");
@@ -18,6 +18,7 @@ package kotlin.reflect.jvm.internal
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.resolve.scopes.JetScope
import org.jetbrains.kotlin.serialization.deserialization.findClassAcrossModuleDependencies
import kotlin.reflect.*
@@ -28,7 +29,7 @@ class KClassImpl<T>(override val jClass: Class<T>) : KCallableContainerImpl(), K
val descriptor by ReflectProperties.lazySoft {
val moduleData = jClass.getOrCreateModule()
val classId = RuntimeTypeMapper.mapJvmClassToKotlinClassId(jClass)
val classId = classId
val descriptor =
if (classId.isLocal()) moduleData.localClassResolver.resolveLocalClass(classId)
@@ -37,11 +38,28 @@ class KClassImpl<T>(override val jClass: Class<T>) : KCallableContainerImpl(), K
descriptor ?: throw KotlinReflectionInternalError("Class not resolved: $jClass")
}
private val classId: ClassId get() = RuntimeTypeMapper.mapJvmClassToKotlinClassId(jClass)
override val scope: JetScope get() = descriptor.getDefaultType().getMemberScope()
override val simpleName: String? get() {
val name = descriptor.getName()
return if (name.isSpecial()) null else name.asString()
val classId = classId
return when {
jClass.isAnonymousClass() -> null
classId.isLocal() -> calculateLocalClassName(jClass)
else -> classId.getRelativeClassName().shortName().asString()
}
}
private fun calculateLocalClassName(jClass: Class<*>): String {
val name = jClass.getSimpleName()
jClass.getEnclosingMethod()?.let { method ->
return name.substringAfter(method.getName() + "$")
}
jClass.getEnclosingConstructor()?.let { constructor ->
return name.substringAfter(constructor.getName() + "$")
}
return name.substringAfter('$')
}
override val properties: Collection<KMemberProperty<T, *>>