From 363c7fd4ea3bcd8a862ecbc63e93c94ca4a20422 Mon Sep 17 00:00:00 2001 From: "Ilya.Kazakevich" Date: Tue, 13 Jun 2017 23:49:57 +0300 Subject: [PATCH] Cache kotlin members because reflection is heavy --- .../jetbrains/reflection/ReflectionUtils.kt | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/python/src/com/jetbrains/reflection/ReflectionUtils.kt b/python/src/com/jetbrains/reflection/ReflectionUtils.kt index 2500de401c24..8220db807a58 100644 --- a/python/src/com/jetbrains/reflection/ReflectionUtils.kt +++ b/python/src/com/jetbrains/reflection/ReflectionUtils.kt @@ -16,8 +16,10 @@ package com.jetbrains.reflection import com.intellij.util.containers.HashMap +import com.intellij.util.containers.SoftHashMap import java.beans.Introspector import java.beans.PropertyDescriptor +import java.lang.ref.SoftReference import java.util.* import kotlin.reflect.KClass import kotlin.reflect.KMutableProperty @@ -98,6 +100,21 @@ private fun KProperty<*>.isAnnotated(annotation: KClass<*>): Boolean { return this.annotations.find { annotation.java.isAssignableFrom(it.javaClass) } != null } + +private val membersCache: MutableMap, SoftReference>>> = SoftHashMap() + +private fun KClass<*>.memberPropertiesCached(): Collection> { + synchronized(membersCache) { + val cache = membersCache[this]?.get() + if (cache != null) { + return cache + } + val memberProperties = this.memberProperties + membersCache.put(this, SoftReference(memberProperties)) + return memberProperties + } +} + /** * @param instance object with properties (see module doc) * @param annotationToFilterByClass optional annotation class to fetch only kotlin properties annotated with it. Only supported in Kotlin @@ -116,7 +133,7 @@ fun getProperties(instance: Any, annotationToFilterByClass: Class<*>? = null, us else { // Kotlin props val klass = instance.javaClass.kotlin - val allKotlinProperties = LinkedHashSet(klass.memberProperties.filterIsInstance(KProperty::class.java)) + val allKotlinProperties = LinkedHashSet(klass.memberPropertiesCached().filterIsInstance(KProperty::class.java)) val delegatedProperties = ArrayList() // See DelegationProperty doc allKotlinProperties.filter { it.isAnnotated(DelegationProperty::class) }.forEach {