Skip to content

Commit bf9f0b1

Browse files
committed
use ValueCreator temp
1 parent 1373c75 commit bf9f0b1

File tree

1 file changed

+24
-66
lines changed

1 file changed

+24
-66
lines changed

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

Lines changed: 24 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,15 @@ package com.fasterxml.jackson.module.kotlin
33
import com.fasterxml.jackson.databind.BeanDescription
44
import com.fasterxml.jackson.databind.DeserializationConfig
55
import com.fasterxml.jackson.databind.DeserializationContext
6-
import com.fasterxml.jackson.databind.MapperFeature
76
import com.fasterxml.jackson.databind.deser.SettableBeanProperty
87
import com.fasterxml.jackson.databind.deser.ValueInstantiator
98
import com.fasterxml.jackson.databind.deser.ValueInstantiators
109
import com.fasterxml.jackson.databind.deser.impl.NullsAsEmptyProvider
1110
import com.fasterxml.jackson.databind.deser.impl.PropertyValueBuffer
1211
import com.fasterxml.jackson.databind.deser.std.StdValueInstantiator
13-
import com.fasterxml.jackson.databind.introspect.AnnotatedConstructor
14-
import com.fasterxml.jackson.databind.introspect.AnnotatedMethod
15-
import java.lang.reflect.Constructor
16-
import java.lang.reflect.Method
1712
import java.lang.reflect.TypeVariable
1813
import kotlin.reflect.KParameter
1914
import kotlin.reflect.KType
20-
import kotlin.reflect.full.extensionReceiverParameter
21-
import kotlin.reflect.full.instanceParameter
22-
import kotlin.reflect.full.valueParameters
23-
import kotlin.reflect.jvm.isAccessible
2415
import kotlin.reflect.jvm.javaType
2516

2617
internal class KotlinValueInstantiator(
@@ -31,62 +22,35 @@ internal class KotlinValueInstantiator(
3122
private val nullIsSameAsDefault: Boolean,
3223
private val strictNullChecks: Boolean
3324
) : StdValueInstantiator(src) {
34-
@Suppress("UNCHECKED_CAST")
3525
override fun createFromObjectWith(
3626
ctxt: DeserializationContext,
3727
props: Array<out SettableBeanProperty>,
3828
buffer: PropertyValueBuffer
3929
): Any? {
40-
val callable = when (_withArgsCreator) {
41-
is AnnotatedConstructor -> cache.kotlinFromJava(_withArgsCreator.annotated as Constructor<Any>)
42-
is AnnotatedMethod -> cache.kotlinFromJava(_withArgsCreator.annotated as Method)
43-
else -> throw IllegalStateException("Expected a constructor or method to create a Kotlin object, instead found ${_withArgsCreator.annotated.javaClass.name}")
44-
} ?: return super.createFromObjectWith(
45-
ctxt,
46-
props,
47-
buffer
48-
) // we cannot reflect this method so do the default Java-ish behavior
49-
50-
if (callable.extensionReceiverParameter != null) {
51-
// we shouldn't have an instance or receiver parameter and if we do, just go with default Java-ish behavior
52-
return super.createFromObjectWith(ctxt, props, buffer)
53-
}
54-
55-
val propCount = props.size + if (callable.instanceParameter != null) 1 else 0
56-
57-
var numCallableParameters = 0
58-
val callableParameters = arrayOfNulls<KParameter>(propCount)
59-
val jsonParamValueList = arrayOfNulls<Any>(propCount)
60-
61-
if (callable.instanceParameter != null) {
62-
val possibleCompanion = callable.instanceParameter!!.type.erasedType().kotlin
63-
64-
if (!possibleCompanion.isCompanion) {
65-
// abort, we have some unknown case here
66-
return super.createFromObjectWith(ctxt, props, buffer)
67-
}
68-
69-
// TODO: cache this lookup since the exception throwing/catching can be expensive
70-
jsonParamValueList[numCallableParameters] = try {
71-
possibleCompanion.objectInstance
72-
} catch (ex: IllegalAccessException) {
73-
// fallback for when an odd access exception happens through Kotlin reflection
74-
val companionField = possibleCompanion.java.enclosingClass.fields.firstOrNull { it.type.kotlin.isCompanion }
75-
?: throw ex
76-
val accessible = companionField.isAccessible
77-
if ((!accessible && ctxt.config.isEnabled(MapperFeature.CAN_OVERRIDE_ACCESS_MODIFIERS)) ||
78-
(accessible && ctxt.config.isEnabled(MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS))
79-
) {
80-
companionField.isAccessible = true
81-
}
82-
companionField.get(null) ?: throw ex
83-
}
84-
85-
callableParameters[numCallableParameters] = callable.instanceParameter
86-
numCallableParameters++
30+
// TODO: cache ValueCreator
31+
val valueCreator: ValueCreator<*> = ValueCreator.of(_withArgsCreator, cache)
32+
?: return super.createFromObjectWith(ctxt, props, buffer)
33+
34+
val propCount: Int
35+
var numCallableParameters: Int
36+
val callableParameters: Array<KParameter?>
37+
val jsonParamValueList: Array<Any?>
38+
39+
if (valueCreator is MethodValueCreator) {
40+
propCount = props.size + 1
41+
numCallableParameters = 1
42+
callableParameters = arrayOfNulls<KParameter>(propCount)
43+
.apply { this[0] = valueCreator.instanceParameter }
44+
jsonParamValueList = arrayOfNulls<Any>(propCount)
45+
.apply { this[0] = valueCreator.companionObjectInstance }
46+
} else {
47+
propCount = props.size
48+
numCallableParameters = 0
49+
callableParameters = arrayOfNulls(propCount)
50+
jsonParamValueList = arrayOfNulls(propCount)
8751
}
8852

89-
callable.valueParameters.forEachIndexed { idx, paramDef ->
53+
valueCreator.valueParameters.forEachIndexed { idx, paramDef ->
9054
val jsonProp = props[idx]
9155
val isMissing = !buffer.hasParameter(jsonProp)
9256

@@ -157,23 +121,17 @@ internal class KotlinValueInstantiator(
157121
numCallableParameters++
158122
}
159123

160-
return if (numCallableParameters == jsonParamValueList.size && callable.instanceParameter == null) {
124+
return if (numCallableParameters == jsonParamValueList.size && valueCreator is ConstructorValueCreator) {
161125
// we didn't do anything special with default parameters, do a normal call
162126
super.createFromObjectWith(ctxt, jsonParamValueList)
163127
} else {
164-
val accessible = callable.isAccessible
165-
if ((!accessible && ctxt.config.isEnabled(MapperFeature.CAN_OVERRIDE_ACCESS_MODIFIERS)) ||
166-
(accessible && ctxt.config.isEnabled(MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS))
167-
) {
168-
callable.isAccessible = true
169-
}
170128
val callableParametersByName = linkedMapOf<KParameter, Any?>()
171129
callableParameters.mapIndexed { idx, paramDef ->
172130
if (paramDef != null) {
173131
callableParametersByName[paramDef] = jsonParamValueList[idx]
174132
}
175133
}
176-
callable.callBy(callableParametersByName)
134+
valueCreator.callBy(callableParametersByName)
177135
}
178136

179137
}

0 commit comments

Comments
 (0)