From 6a97dc5f2ca573bb6061162d18d70ddc087d303b Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Wed, 17 Aug 2016 17:57:12 +0300 Subject: [PATCH] Cache declared/non-declared static/non-static KClass members Making KClassImpl.Data, its superclass and ReflectProperties public was required because they are accessed from other package in KClasses.kt --- .../src/kotlin/reflect/KClasses.kt | 39 ++++++------------- .../kotlin/reflect/jvm/internal/KClassImpl.kt | 26 +++++++++++-- .../jvm/internal/KDeclarationContainerImpl.kt | 36 +++++++++-------- .../reflect/jvm/internal/KPackageImpl.kt | 18 +++++---- .../jvm/internal/ReflectProperties.java | 2 +- 5 files changed, 66 insertions(+), 55 deletions(-) diff --git a/core/reflection.jvm/src/kotlin/reflect/KClasses.kt b/core/reflection.jvm/src/kotlin/reflect/KClasses.kt index 4077d46f404..2d8b15f1db4 100644 --- a/core/reflection.jvm/src/kotlin/reflect/KClasses.kt +++ b/core/reflection.jvm/src/kotlin/reflect/KClasses.kt @@ -70,10 +70,7 @@ val KClass<*>.defaultType: KType * Does not include members declared in supertypes. */ val KClass<*>.declaredMembers: Collection> - get() = with(this as KClassImpl) { - (getMembers(memberScope, declaredOnly = true) + - getMembers(staticScope, declaredOnly = true)).toList() - } + get() = (this as KClassImpl).data().declaredMembers.toList() /** * Returns all functions declared in this class, including all non-static methods declared in the class @@ -86,8 +83,7 @@ val KClass<*>.functions: Collection> * Returns static functions declared in this class. */ val KClass<*>.staticFunctions: Collection> - get() = (this as KClassImpl) - .getMembers(staticScope, declaredOnly = false) + get() = (this as KClassImpl).data().allStaticMembers .filterIsInstance>() .toList() @@ -95,8 +91,7 @@ val KClass<*>.staticFunctions: Collection> * Returns non-extension non-static functions declared in this class and all of its superclasses. */ val KClass<*>.memberFunctions: Collection> - get() = (this as KClassImpl) - .getMembers(memberScope, declaredOnly = false) + get() = (this as KClassImpl).data().allNonStaticMembers .filterNotExtensions() .filterIsInstance>() .toList() @@ -105,8 +100,7 @@ val KClass<*>.memberFunctions: Collection> * Returns extension functions declared in this class and all of its superclasses. */ val KClass<*>.memberExtensionFunctions: Collection> - get() = (this as KClassImpl) - .getMembers(memberScope, declaredOnly = false) + get() = (this as KClassImpl).data().allNonStaticMembers .filterExtensions() .filterIsInstance>() .toList() @@ -117,9 +111,7 @@ val KClass<*>.memberExtensionFunctions: Collection> * declared in the class and the superclasses, as well as static methods declared in the class. */ val KClass<*>.declaredFunctions: Collection> - get() = (this as KClassImpl) - .getMembers(memberScope, declaredOnly = true) - .plus(getMembers(staticScope, declaredOnly = true)) + get() = (this as KClassImpl).data().declaredMembers .filterIsInstance>() .toList() @@ -127,8 +119,7 @@ val KClass<*>.declaredFunctions: Collection> * Returns non-extension non-static functions declared in this class. */ val KClass<*>.declaredMemberFunctions: Collection> - get() = (this as KClassImpl) - .getMembers(memberScope, declaredOnly = true) + get() = (this as KClassImpl).data().declaredNonStaticMembers .filterNotExtensions() .filterIsInstance>() .toList() @@ -137,8 +128,7 @@ val KClass<*>.declaredMemberFunctions: Collection> * Returns extension functions declared in this class. */ val KClass<*>.declaredMemberExtensionFunctions: Collection> - get() = (this as KClassImpl) - .getMembers(memberScope, declaredOnly = true) + get() = (this as KClassImpl).data().declaredNonStaticMembers .filterExtensions() .filterIsInstance>() .toList() @@ -148,8 +138,7 @@ val KClass<*>.declaredMemberExtensionFunctions: Collection> * Only properties representing static fields of Java classes are considered static. */ val KClass<*>.staticProperties: Collection> - get() = (this as KClassImpl) - .getMembers(staticScope, declaredOnly = false) + get() = (this as KClassImpl).data().allStaticMembers .filterNotExtensions() .filterIsInstance>() .toList() @@ -158,8 +147,7 @@ val KClass<*>.staticProperties: Collection> * Returns non-extension properties declared in this class and all of its superclasses. */ val KClass.memberProperties: Collection> - get() = (this as KClassImpl) - .getMembers(memberScope, declaredOnly = false) + get() = (this as KClassImpl).data().allNonStaticMembers .filterNotExtensions() .filterIsInstance>() .toList() @@ -168,8 +156,7 @@ val KClass.memberProperties: Collection> * Returns extension properties declared in this class and all of its superclasses. */ val KClass.memberExtensionProperties: Collection> - get() = (this as KClassImpl) - .getMembers(memberScope, declaredOnly = false) + get() = (this as KClassImpl).data().allNonStaticMembers .filterExtensions() .filterIsInstance>() .toList() @@ -178,8 +165,7 @@ val KClass.memberExtensionProperties: Collection KClass.declaredMemberProperties: Collection> - get() = (this as KClassImpl) - .getMembers(memberScope, declaredOnly = true) + get() = (this as KClassImpl).data().declaredNonStaticMembers .filterNotExtensions() .filterIsInstance>() .toList() @@ -188,8 +174,7 @@ val KClass.declaredMemberProperties: Collection> * Returns extension properties declared in this class. */ val KClass.declaredMemberExtensionProperties: Collection> - get() = (this as KClassImpl) - .getMembers(memberScope, declaredOnly = true) + get() = (this as KClassImpl).data().declaredNonStaticMembers .filterExtensions() .filterIsInstance>() .toList() diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KClassImpl.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KClassImpl.kt index 99a0c20c1ee..21de91830ce 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KClassImpl.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KClassImpl.kt @@ -32,10 +32,12 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.serialization.deserialization.findClassAcrossModuleDependencies import kotlin.jvm.internal.TypeIntrinsics import kotlin.reflect.* +import kotlin.reflect.jvm.internal.KDeclarationContainerImpl.MemberBelonginess.DECLARED +import kotlin.reflect.jvm.internal.KDeclarationContainerImpl.MemberBelonginess.INHERITED internal class KClassImpl(override val jClass: Class) : KDeclarationContainerImpl(), KClass, KClassifierImpl, KAnnotatedElementImpl { - private inner class Data : KDeclarationContainerImpl.Data() { + inner class Data : KDeclarationContainerImpl.Data() { val descriptor: ClassDescriptor by ReflectProperties.lazySoft { val classId = classId val moduleData = data().moduleData @@ -60,9 +62,26 @@ internal class KClassImpl(override val jClass: Class) : } field.get(null) as T } + + val declaredNonStaticMembers: Sequence> + by ReflectProperties.lazySoft { getMembers(memberScope, DECLARED) } + val declaredStaticMembers: Sequence> + by ReflectProperties.lazySoft { getMembers(staticScope, DECLARED) } + val inheritedNonStaticMembers: Sequence> + by ReflectProperties.lazySoft { getMembers(memberScope, INHERITED) } + val inheritedStaticMembers: Sequence> + by ReflectProperties.lazySoft { getMembers(staticScope, INHERITED) } + + val allNonStaticMembers: Sequence> get() = declaredNonStaticMembers + inheritedNonStaticMembers + val allStaticMembers: Sequence> get() = declaredStaticMembers + inheritedStaticMembers + val declaredMembers: Sequence> get() = declaredNonStaticMembers + declaredStaticMembers + + val allMembers: Collection> by ReflectProperties.lazySoft { + (allNonStaticMembers + allStaticMembers).toList() + } } - private val data = ReflectProperties.lazy { Data() } + val data = ReflectProperties.lazy { Data() } override val descriptor: ClassDescriptor get() = data().descriptor @@ -74,8 +93,7 @@ internal class KClassImpl(override val jClass: Class) : internal val staticScope: MemberScope get() = descriptor.staticScope - override val members: Collection> - get() = (getMembers(memberScope, declaredOnly = false) + getMembers(staticScope, declaredOnly = false)).toList() + override val members: Collection> get() = data().allMembers override val constructorDescriptors: Collection get() { diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KDeclarationContainerImpl.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KDeclarationContainerImpl.kt index 1a47c29cd71..896a714632b 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KDeclarationContainerImpl.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KDeclarationContainerImpl.kt @@ -31,7 +31,7 @@ import kotlin.jvm.internal.ClassBasedDeclarationContainer import kotlin.reflect.KotlinReflectionInternalError internal abstract class KDeclarationContainerImpl : ClassBasedDeclarationContainer { - protected abstract inner class Data { + abstract inner class Data { // This is stored here on a soft reference to prevent GC from destroying the weak reference to it in the moduleByClassLoader cache val moduleData: RuntimeModuleData by ReflectProperties.lazySoft { jClass.getOrCreateModule() @@ -47,33 +47,37 @@ internal abstract class KDeclarationContainerImpl : ClassBasedDeclarationContain abstract fun getFunctions(name: Name): Collection - fun getMembers(scope: MemberScope, declaredOnly: Boolean): Sequence> { - val visitor = object : DeclarationDescriptorVisitorEmptyBodies?, Unit>() { - private fun skipCallable(descriptor: CallableMemberDescriptor): Boolean = - declaredOnly && !descriptor.kind.isReal + protected fun getMembers(scope: MemberScope, belonginess: MemberBelonginess): Sequence> { + val visitor = object : DeclarationDescriptorVisitorEmptyBodies, Unit>() { + override fun visitPropertyDescriptor(descriptor: PropertyDescriptor, data: Unit): KCallableImpl<*> = + createProperty(descriptor) - override fun visitPropertyDescriptor(descriptor: PropertyDescriptor, data: Unit): KCallableImpl<*>? { - return if (skipCallable(descriptor)) null else createProperty(descriptor) - } + override fun visitFunctionDescriptor(descriptor: FunctionDescriptor, data: Unit): KCallableImpl<*> = + KFunctionImpl(this@KDeclarationContainerImpl, descriptor) - override fun visitFunctionDescriptor(descriptor: FunctionDescriptor, data: Unit): KCallableImpl<*>? { - return if (skipCallable(descriptor)) null else KFunctionImpl(this@KDeclarationContainerImpl, descriptor) - } - - override fun visitConstructorDescriptor(descriptor: ConstructorDescriptor, data: Unit): KCallableImpl<*>? { - throw IllegalStateException("No constructors should appear in this scope: $descriptor") - } + override fun visitConstructorDescriptor(descriptor: ConstructorDescriptor, data: Unit): KCallableImpl<*> = + throw IllegalStateException("No constructors should appear in this scope: $descriptor") } return scope.getContributedDescriptors().asSequence() .filter { descriptor -> - descriptor !is MemberDescriptor || descriptor.visibility != Visibilities.INVISIBLE_FAKE + descriptor is CallableMemberDescriptor && + descriptor.visibility != Visibilities.INVISIBLE_FAKE && + belonginess.accept(descriptor) } .mapNotNull { descriptor -> descriptor.accept(visitor, Unit) } } + protected enum class MemberBelonginess { + DECLARED, + INHERITED; + + fun accept(member: CallableMemberDescriptor): Boolean = + member.kind.isReal == (this == DECLARED) + } + private fun createProperty(descriptor: PropertyDescriptor): KPropertyImpl<*> { val receiverCount = (descriptor.dispatchReceiverParameter?.let { 1 } ?: 0) + (descriptor.extensionReceiverParameter?.let { 1 } ?: 0) diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KPackageImpl.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KPackageImpl.kt index e64b5784d52..c8d597c5c34 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KPackageImpl.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KPackageImpl.kt @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor import kotlin.reflect.KCallable +import kotlin.reflect.jvm.internal.KDeclarationContainerImpl.MemberBelonginess.DECLARED internal class KPackageImpl(override val jClass: Class<*>, val moduleName: String) : KDeclarationContainerImpl() { private inner class Data : KDeclarationContainerImpl.Data() { @@ -48,6 +49,15 @@ internal class KPackageImpl(override val jClass: Class<*>, val moduleName: Strin jClass } } + + val members: Collection> by ReflectProperties.lazySoft { + getMembers(scope, DECLARED).filter { member -> + val callableDescriptor = member.descriptor as DeserializedCallableMemberDescriptor + val packageFragment = callableDescriptor.containingDeclaration as PackageFragmentDescriptor + val source = (packageFragment as? LazyJavaPackageFragment)?.source as? KotlinJvmBinaryPackageSourceElement + (source?.getContainingBinaryClass(callableDescriptor) as? ReflectKotlinClass)?.klass == jClass + }.toList() + } } private val data = ReflectProperties.lazy { Data() } @@ -56,13 +66,7 @@ internal class KPackageImpl(override val jClass: Class<*>, val moduleName: Strin private val scope: MemberScope get() = data().descriptor.memberScope - override val members: Collection> - get() = getMembers(scope, declaredOnly = false).filter { member -> - val callableDescriptor = member.descriptor as DeserializedCallableMemberDescriptor - val packageFragment = callableDescriptor.containingDeclaration as PackageFragmentDescriptor - val source = (packageFragment as? LazyJavaPackageFragment)?.source as? KotlinJvmBinaryPackageSourceElement - (source?.getContainingBinaryClass(callableDescriptor) as? ReflectKotlinClass)?.klass == jClass - }.toList() + override val members: Collection> get() = data().members override val constructorDescriptors: Collection get() = emptyList() diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/ReflectProperties.java b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/ReflectProperties.java index 0175b1fd5b0..9eacc7f47b1 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/ReflectProperties.java +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/ReflectProperties.java @@ -23,7 +23,7 @@ import org.jetbrains.annotations.Nullable; import java.lang.ref.SoftReference; import java.lang.ref.WeakReference; -/* package */ class ReflectProperties { +public class ReflectProperties { public static abstract class Val { private static final Object NULL_VALUE = new Object() {};