Support reflection calls to multifile class members

#KT-11447 Fixed
This commit is contained in:
Alexander Udalov
2016-03-22 15:21:09 +03:00
parent 9fa101b3fe
commit 6924d883eb
6 changed files with 171 additions and 4 deletions
@@ -39,6 +39,9 @@ internal abstract class KDeclarationContainerImpl : ClassBasedDeclarationContain
val moduleData: RuntimeModuleData
get() = moduleData_()
protected open val methodOwner: Class<*>
get() = jClass
abstract val constructorDescriptors: Collection<ConstructorDescriptor>
abstract fun getProperties(name: Name): Collection<PropertyDescriptor>
@@ -175,9 +178,7 @@ internal abstract class KDeclarationContainerImpl : ClassBasedDeclarationContain
fun findMethodBySignature(name: String, desc: String, declared: Boolean): Method? {
if (name == "<init>") return null
// Method for a top level function should be the one from the package facade.
// This is likely to change after the package part reform.
return jClass.tryGetMethod(name, loadParameterTypes(desc), declared)
return methodOwner.tryGetMethod(name, loadParameterTypes(desc), declared)
}
fun findDefaultMethod(name: String, desc: String, isMember: Boolean, declared: Boolean): Method? {
@@ -189,7 +190,7 @@ internal abstract class KDeclarationContainerImpl : ClassBasedDeclarationContain
}
addParametersAndMasks(parameterTypes, desc, false)
return jClass.tryGetMethod(name + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, parameterTypes, declared)
return methodOwner.tryGetMethod(name + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, parameterTypes, declared)
}
fun findConstructorBySignature(desc: String, declared: Boolean): Constructor<*>? {
@@ -38,6 +38,19 @@ internal class KPackageImpl(override val jClass: Class<*>, val moduleName: Strin
}
}
override val methodOwner: Class<*> by lazy(LazyThreadSafetyMode.PUBLICATION) {
val facadeName = ReflectKotlinClass.create(jClass)?.classHeader?.multifileClassName
// We need to check isNotEmpty because this is the value read from the annotation which cannot be null.
// The default value for 'xs' is empty string, as declared in kotlin.Metadata
// TODO: do not read ReflectKotlinClass multiple times, obtain facade name from descriptor
if (facadeName != null && facadeName.isNotEmpty()) {
jClass.classLoader.loadClass(facadeName.replace('/', '.'))
}
else {
jClass
}
}
internal val scope: MemberScope get() = descriptor().memberScope
override val members: Collection<KCallable<*>>