Cache kotlin members because reflection is heavy

This commit is contained in:
Ilya.Kazakevich
2017-06-14 19:13:47 +03:00
parent 73f5aa78e1
commit 363c7fd4ea
@@ -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<KClass<*>, SoftReference<Collection<KProperty<*>>>> = SoftHashMap()
private fun KClass<*>.memberPropertiesCached(): Collection<KProperty<*>> {
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<Property>() // See DelegationProperty doc
allKotlinProperties.filter { it.isAnnotated(DelegationProperty::class) }.forEach {