Reflection: support Java anonymous/local classes
Local classes and anonymous objects are normal classes and kotlin-reflect can load all declarations and modifiers from them, and support calling members, exactly in the same way as it does for normal non-local classes. #KT-41373 In Progress
This commit is contained in:
committed by
Space Team
parent
1e031d9fb8
commit
d833b732c9
+2
-3
@@ -116,9 +116,8 @@ fun box(): String {
|
|||||||
checkKotlinAnonymousObject()
|
checkKotlinAnonymousObject()
|
||||||
checkKotlinLocalClass()
|
checkKotlinLocalClass()
|
||||||
|
|
||||||
// TODO: fails with KotlinReflectionInternalError: Unresolved class: class JavaClass$1 (kind = null)
|
checkJavaAnonymousObject()
|
||||||
// checkJavaAnonymousObject()
|
checkJavaLocalClass()
|
||||||
// checkJavaLocalClass()
|
|
||||||
|
|
||||||
return "OK"
|
return "OK"
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-1
@@ -105,7 +105,14 @@ class ReflectJavaClass(
|
|||||||
get() = null
|
get() = null
|
||||||
|
|
||||||
override val name: Name
|
override val name: Name
|
||||||
get() = Name.identifier(klass.simpleName)
|
get() = if (klass.isAnonymousClass) {
|
||||||
|
// For anonymous classes, `Class.simpleName` returns an empty string in Java reflection.
|
||||||
|
// We don't want that because it breaks all sorts of invariants on names which cannot be empty in Kotlin.
|
||||||
|
// So we extract the simple name from the full JVM binary name, e.g. "org.test.Foo$1" -> "Foo$1".
|
||||||
|
Name.identifier(klass.name.substringAfterLast("."))
|
||||||
|
} else {
|
||||||
|
Name.identifier(klass.simpleName)
|
||||||
|
}
|
||||||
|
|
||||||
override val typeParameters: List<ReflectJavaTypeParameter>
|
override val typeParameters: List<ReflectJavaTypeParameter>
|
||||||
get() = klass.typeParameters.map(::ReflectJavaTypeParameter)
|
get() = klass.typeParameters.map(::ReflectJavaTypeParameter)
|
||||||
|
|||||||
@@ -51,8 +51,13 @@ internal class KClassImpl<T : Any>(
|
|||||||
val moduleData = data.value.moduleData
|
val moduleData = data.value.moduleData
|
||||||
|
|
||||||
val descriptor =
|
val descriptor =
|
||||||
if (classId.isLocal) moduleData.deserialization.deserializeClass(classId)
|
if (classId.isLocal && jClass.isAnnotationPresent(Metadata::class.java)) {
|
||||||
else moduleData.module.findClassAcrossModuleDependencies(classId)
|
// If it's a Kotlin local class or anonymous object, deserialize its metadata directly because it cannot be found via
|
||||||
|
// `module.findClassAcrossModuleDependencies`.
|
||||||
|
moduleData.deserialization.deserializeClass(classId)
|
||||||
|
} else {
|
||||||
|
moduleData.module.findClassAcrossModuleDependencies(classId)
|
||||||
|
}
|
||||||
|
|
||||||
descriptor ?: reportUnresolvedClass()
|
descriptor ?: reportUnresolvedClass()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user