Skip to content

Commit a166033

Browse files
committed
fix to use cache
1 parent bf9f0b1 commit a166033

File tree

3 files changed

+35
-20
lines changed

3 files changed

+35
-20
lines changed

src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinValueInstantiator.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@ internal class KotlinValueInstantiator(
2727
props: Array<out SettableBeanProperty>,
2828
buffer: PropertyValueBuffer
2929
): Any? {
30-
// TODO: cache ValueCreator
31-
val valueCreator: ValueCreator<*> = ValueCreator.of(_withArgsCreator, cache)
30+
val valueCreator: ValueCreator<*> = cache.valueCreatorFromJava(_withArgsCreator)
3231
?: return super.createFromObjectWith(ctxt, props, buffer)
3332

3433
val propCount: Int

src/main/kotlin/com/fasterxml/jackson/module/kotlin/ReflectionCache.kt

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package com.fasterxml.jackson.module.kotlin
33
import com.fasterxml.jackson.databind.introspect.AnnotatedConstructor
44
import com.fasterxml.jackson.databind.introspect.AnnotatedMember
55
import com.fasterxml.jackson.databind.introspect.AnnotatedMethod
6+
import com.fasterxml.jackson.databind.introspect.AnnotatedWithParams
67
import com.fasterxml.jackson.databind.util.LRUMap
78
import java.lang.reflect.Constructor
89
import java.lang.reflect.Method
@@ -35,6 +36,8 @@ internal class ReflectionCache(reflectionCacheSize: Int) {
3536
private val javaClassToKotlin = LRUMap<Class<Any>, KClass<Any>>(reflectionCacheSize, reflectionCacheSize)
3637
private val javaConstructorToKotlin = LRUMap<Constructor<Any>, KFunction<Any>>(reflectionCacheSize, reflectionCacheSize)
3738
private val javaMethodToKotlin = LRUMap<Method, KFunction<*>>(reflectionCacheSize, reflectionCacheSize)
39+
private val javaConstructorToValueCreator = LRUMap<Constructor<Any>, ConstructorValueCreator<*>>(reflectionCacheSize, reflectionCacheSize)
40+
private val javaMethodToValueCreator = LRUMap<Method, MethodValueCreator<*>>(reflectionCacheSize, reflectionCacheSize)
3841
private val javaConstructorIsCreatorAnnotated = LRUMap<AnnotatedConstructor, Boolean>(reflectionCacheSize, reflectionCacheSize)
3942
private val javaMemberIsRequired = LRUMap<AnnotatedMember, BooleanTriState?>(reflectionCacheSize, reflectionCacheSize)
4043
private val kotlinGeneratedMethod = LRUMap<AnnotatedMethod, Boolean>(reflectionCacheSize, reflectionCacheSize)
@@ -49,6 +52,37 @@ internal class ReflectionCache(reflectionCacheSize: Int) {
4952
fun kotlinFromJava(key: Method): KFunction<*>? = javaMethodToKotlin.get(key)
5053
?: key.kotlinFunction?.let { javaMethodToKotlin.putIfAbsent(key, it) ?: it }
5154

55+
/**
56+
* return null if...
57+
* - can't get kotlinFunction
58+
* - contains extensionReceiverParameter
59+
* - instance parameter is not companion object or can't get
60+
*/
61+
@Suppress("UNCHECKED_CAST")
62+
fun valueCreatorFromJava(_withArgsCreator: AnnotatedWithParams): ValueCreator<*>? = when (_withArgsCreator) {
63+
is AnnotatedConstructor -> {
64+
val constructor = _withArgsCreator.annotated as Constructor<Any>
65+
66+
javaConstructorToValueCreator.get(constructor)
67+
?: kotlinFromJava(constructor)?.let {
68+
val value = ConstructorValueCreator(it)
69+
70+
javaConstructorToValueCreator.putIfAbsent(constructor, value) ?: value
71+
}
72+
}
73+
is AnnotatedMethod -> {
74+
val method = _withArgsCreator.annotated as Method
75+
76+
javaMethodToValueCreator.get(method)
77+
?: kotlinFromJava(method)?.let {
78+
val value = MethodValueCreator.of(it)
79+
80+
javaMethodToValueCreator.putIfAbsent(method, value) ?: value
81+
}
82+
}
83+
else -> throw IllegalStateException("Expected a constructor or method to create a Kotlin object, instead found ${_withArgsCreator.annotated.javaClass.name}")
84+
} // we cannot reflect this method so do the default Java-ish behavior
85+
5286
fun checkConstructorIsCreatorAnnotated(key: AnnotatedConstructor, calc: (AnnotatedConstructor) -> Boolean): Boolean = javaConstructorIsCreatorAnnotated.get(key)
5387
?: calc(key).let { javaConstructorIsCreatorAnnotated.putIfAbsent(key, it) ?: it }
5488

src/main/kotlin/com/fasterxml/jackson/module/kotlin/ValueCreator.kt

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,6 @@ package com.fasterxml.jackson.module.kotlin
22

33
import com.fasterxml.jackson.databind.DeserializationContext
44
import com.fasterxml.jackson.databind.MapperFeature
5-
import com.fasterxml.jackson.databind.introspect.AnnotatedConstructor
6-
import com.fasterxml.jackson.databind.introspect.AnnotatedMethod
7-
import com.fasterxml.jackson.databind.introspect.AnnotatedWithParams
8-
import java.lang.reflect.Constructor
9-
import java.lang.reflect.Method
105
import kotlin.reflect.KFunction
116
import kotlin.reflect.KParameter
127
import kotlin.reflect.full.valueParameters
@@ -48,17 +43,4 @@ internal sealed class ValueCreator<T> {
4843
* Function call with default values enabled.
4944
*/
5045
fun callBy(args: Map<KParameter, Any?>): T = callable.callBy(args)
51-
52-
companion object {
53-
@Suppress("UNCHECKED_CAST")
54-
fun of(
55-
_withArgsCreator: AnnotatedWithParams, cache: ReflectionCache
56-
): ValueCreator<*>? = when (_withArgsCreator) {
57-
is AnnotatedConstructor -> cache.kotlinFromJava(_withArgsCreator.annotated as Constructor<Any>)
58-
?.let { ConstructorValueCreator(it) }
59-
is AnnotatedMethod -> cache.kotlinFromJava(_withArgsCreator.annotated as Method)
60-
?.let { MethodValueCreator.of(it) }
61-
else -> throw IllegalStateException("Expected a constructor or method to create a Kotlin object, instead found ${_withArgsCreator.annotated.javaClass.name}")
62-
} // we cannot reflect this method so do the default Java-ish behavior
63-
}
6446
}

0 commit comments

Comments
 (0)