From c7050ed4459276cdd4500ce1393dd69b69e9d05a Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Tue, 6 Sep 2016 11:49:19 +0300 Subject: [PATCH] Cache everything cacheable in KClassImpl #KT-10651 Fixed --- .../kotlin/reflect/jvm/internal/KClassImpl.kt | 138 ++++++++++-------- 1 file changed, 77 insertions(+), 61 deletions(-) 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 21de91830ce..710a98cf276 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KClassImpl.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KClassImpl.kt @@ -49,6 +49,52 @@ internal class KClassImpl(override val jClass: Class) : descriptor ?: reportUnresolvedClass() } + val simpleName: String? by ReflectProperties.lazySoft { + if (jClass.isAnonymousClass) return@lazySoft null + + val classId = classId + when { + classId.isLocal -> calculateLocalClassName(jClass) + else -> classId.shortClassName.asString() + } + } + + val qualifiedName: String? by ReflectProperties.lazySoft { + if (jClass.isAnonymousClass) return@lazySoft null + + val classId = classId + when { + classId.isLocal -> null + else -> classId.asSingleFqName().asString() + } + } + + private fun calculateLocalClassName(jClass: Class<*>): String { + val name = jClass.simpleName + jClass.enclosingMethod?.let { method -> + return name.substringAfter(method.name + "$") + } + jClass.enclosingConstructor?.let { constructor -> + return name.substringAfter(constructor.name + "$") + } + return name.substringAfter('$') + } + + @Suppress("UNCHECKED_CAST") + val constructors: Collection> by ReflectProperties.lazySoft { + constructorDescriptors.map { descriptor -> + KFunctionImpl(this@KClassImpl, descriptor) as KFunction + } + } + + val nestedClasses: Collection> by ReflectProperties.lazySoft { + descriptor.unsubstitutedInnerClassesScope.getContributedDescriptors().filterNot(DescriptorUtils::isEnumEntry).mapNotNull { + nestedClass -> + val jClass = (nestedClass as ClassDescriptor).toJavaClass() + jClass?.let { KClassImpl(it) } + } + } + @Suppress("UNCHECKED_CAST") val objectInstance: T? by ReflectProperties.lazy { val descriptor = descriptor @@ -63,6 +109,31 @@ internal class KClassImpl(override val jClass: Class) : field.get(null) as T } + val typeParameters: List by ReflectProperties.lazySoft { + descriptor.declaredTypeParameters.map(::KTypeParameterImpl) + } + + val supertypes: List by ReflectProperties.lazySoft { + descriptor.typeConstructor.supertypes.map { kotlinType -> + KTypeImpl(kotlinType) { + val superClass = kotlinType.constructor.declarationDescriptor + if (superClass !is ClassDescriptor) throw KotlinReflectionInternalError("Supertype not a class: $superClass") + + val superJavaClass = superClass.toJavaClass() + ?: throw KotlinReflectionInternalError("Unsupported superclass of $this: $superClass") + + if (jClass.superclass == superJavaClass) { + jClass.genericSuperclass + } + else { + val index = jClass.interfaces.indexOf(superJavaClass) + if (index < 0) throw KotlinReflectionInternalError("No superclass of $this in Java reflection for $superClass") + jClass.genericInterfaces[index] + } + } + } + } + val declaredNonStaticMembers: Sequence> by ReflectProperties.lazySoft { getMembers(memberScope, DECLARED) } val declaredStaticMembers: Sequence> @@ -112,49 +183,13 @@ internal class KClassImpl(override val jClass: Class) : memberScope.getContributedFunctions(name, NoLookupLocation.FROM_REFLECTION) + staticScope.getContributedFunctions(name, NoLookupLocation.FROM_REFLECTION) - override val simpleName: String? get() { - if (jClass.isAnonymousClass) return null + override val simpleName: String? get() = data().simpleName - val classId = classId - return when { - classId.isLocal -> calculateLocalClassName(jClass) - else -> classId.shortClassName.asString() - } - } + override val qualifiedName: String? get() = data().qualifiedName - private fun calculateLocalClassName(jClass: Class<*>): String { - val name = jClass.simpleName - jClass.enclosingMethod?.let { method -> - return name.substringAfter(method.name + "$") - } - jClass.enclosingConstructor?.let { constructor -> - return name.substringAfter(constructor.name + "$") - } - return name.substringAfter('$') - } + override val constructors: Collection> get() = data().constructors - override val qualifiedName: String? get() { - if (jClass.isAnonymousClass) return null - - val classId = classId - return when { - classId.isLocal -> null - else -> classId.asSingleFqName().asString() - } - } - - @Suppress("UNCHECKED_CAST") - override val constructors: Collection> - get() = constructorDescriptors.map { - KFunctionImpl(this, it) as KFunction - } - - override val nestedClasses: Collection> - get() = descriptor.unsubstitutedInnerClassesScope.getContributedDescriptors().filterNot(DescriptorUtils::isEnumEntry).mapNotNull { - nestedClass -> - val jClass = (nestedClass as ClassDescriptor).toJavaClass() - jClass?.let { KClassImpl(it) } - } + override val nestedClasses: Collection> get() = data().nestedClasses override val objectInstance: T? get() = data().objectInstance @@ -166,28 +201,9 @@ internal class KClassImpl(override val jClass: Class) : return (jClass.wrapperByPrimitive ?: jClass).isInstance(value) } - override val typeParameters: List - get() = descriptor.declaredTypeParameters.map(::KTypeParameterImpl) + override val typeParameters: List get() = data().typeParameters - override val supertypes: List - get() = descriptor.typeConstructor.supertypes.map { kotlinType -> - KTypeImpl(kotlinType) { - val superClass = kotlinType.constructor.declarationDescriptor - if (superClass !is ClassDescriptor) throw KotlinReflectionInternalError("Supertype not a class: $superClass") - - val superJavaClass = superClass.toJavaClass() - ?: throw KotlinReflectionInternalError("Unsupported superclass of $this: $superClass") - - if (jClass.superclass == superJavaClass) { - jClass.genericSuperclass - } - else { - val index = jClass.interfaces.indexOf(superJavaClass) - if (index < 0) throw KotlinReflectionInternalError("No superclass of $this in Java reflection for $superClass") - jClass.genericInterfaces[index] - } - } - } + override val supertypes: List get() = data().supertypes override val visibility: KVisibility? get() = descriptor.visibility.toKVisibility()