Reflection: create synthetic classes for Java lambdas

... as well as $SwitchMap and other synthetic classes generated by javac
or other JVM language compilers or runtimes.

Note that for Kotlin, all synthetic classes were already handled by the
subsequent check for `KotlinClassHeader.Kind.SYNTHETIC_CLASS`, but after
this change we won't call `ReflectKotlinClass.create` for those, which
is a minor optimization.

 #KT-41373 Fixed
This commit is contained in:
Alexander Udalov
2023-03-28 20:45:48 +02:00
committed by Space Team
parent 5dc882abf5
commit f5bbf2b4fe
2 changed files with 10 additions and 3 deletions
@@ -90,9 +90,7 @@ fun box(): String {
checkMultifileClass()
checkMultifileClassPart()
checkKotlinLambda()
// TODO: fails with KotlinReflectionInternalError: Unresolved class: class JavaClass$$Lambda$1166/180251002 (kind = null)
// checkJavaLambda()
checkJavaLambda()
return "OK"
}
@@ -316,6 +316,15 @@ internal class KClassImpl<T : Any>(
}
private fun createSyntheticClassOrFail(classId: ClassId, moduleData: RuntimeModuleData): ClassDescriptor {
if (jClass.isSynthetic) {
// Synthetic classes, either from Java or from Kotlin, have no Kotlin metadata and no reliable way (and probably no use cases)
// to introspect, so we create an empty synthetic class descriptor for them.
// This is especially useful for Java lambdas which have names like `JavaClass$$Lambda$4711/1112495601` and are NOT recognized
// as local or anonymous classes (j.l.Class.isLocalClass/isAnonymousClass return false), which breaks some invariants in the
// subsequent code in kotlin-reflect if it tries to interpret them as normal anonymous classes and load their members.
return createSyntheticClass(classId, moduleData)
}
when (val kind = ReflectKotlinClass.create(jClass)?.classHeader?.kind) {
KotlinClassHeader.Kind.FILE_FACADE,
KotlinClassHeader.Kind.MULTIFILE_CLASS,