@@ -3,24 +3,15 @@ package com.fasterxml.jackson.module.kotlin
3
3
import com.fasterxml.jackson.databind.BeanDescription
4
4
import com.fasterxml.jackson.databind.DeserializationConfig
5
5
import com.fasterxml.jackson.databind.DeserializationContext
6
- import com.fasterxml.jackson.databind.MapperFeature
7
6
import com.fasterxml.jackson.databind.deser.SettableBeanProperty
8
7
import com.fasterxml.jackson.databind.deser.ValueInstantiator
9
8
import com.fasterxml.jackson.databind.deser.ValueInstantiators
10
9
import com.fasterxml.jackson.databind.deser.impl.NullsAsEmptyProvider
11
10
import com.fasterxml.jackson.databind.deser.impl.PropertyValueBuffer
12
11
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
17
12
import java.lang.reflect.TypeVariable
18
13
import kotlin.reflect.KParameter
19
14
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
24
15
import kotlin.reflect.jvm.javaType
25
16
26
17
internal class KotlinValueInstantiator (
@@ -31,62 +22,34 @@ internal class KotlinValueInstantiator(
31
22
private val nullIsSameAsDefault : Boolean ,
32
23
private val strictNullChecks : Boolean
33
24
) : StdValueInstantiator(src) {
34
- @Suppress(" UNCHECKED_CAST" )
35
25
override fun createFromObjectWith (
36
26
ctxt : DeserializationContext ,
37
27
props : Array <out SettableBeanProperty >,
38
28
buffer : PropertyValueBuffer
39
29
): 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
+ val valueCreator: ValueCreator <* > = cache.valueCreatorFromJava(_withArgsCreator )
31
+ ? : return super .createFromObjectWith(ctxt, props, buffer)
32
+
33
+ val propCount: Int
34
+ var numCallableParameters: Int
35
+ val callableParameters: Array <KParameter ?>
36
+ val jsonParamValueList: Array <Any ?>
37
+
38
+ if (valueCreator is MethodValueCreator ) {
39
+ propCount = props.size + 1
40
+ numCallableParameters = 1
41
+ callableParameters = arrayOfNulls<KParameter >(propCount)
42
+ .apply { this [0 ] = valueCreator.instanceParameter }
43
+ jsonParamValueList = arrayOfNulls<Any >(propCount)
44
+ .apply { this [0 ] = valueCreator.companionObjectInstance }
45
+ } else {
46
+ propCount = props.size
47
+ numCallableParameters = 0
48
+ callableParameters = arrayOfNulls(propCount)
49
+ jsonParamValueList = arrayOfNulls(propCount)
87
50
}
88
51
89
- callable .valueParameters.forEachIndexed { idx, paramDef ->
52
+ valueCreator .valueParameters.forEachIndexed { idx, paramDef ->
90
53
val jsonProp = props[idx]
91
54
val isMissing = ! buffer.hasParameter(jsonProp)
92
55
@@ -157,23 +120,19 @@ internal class KotlinValueInstantiator(
157
120
numCallableParameters++
158
121
}
159
122
160
- return if (numCallableParameters == jsonParamValueList.size && callable.instanceParameter == null ) {
123
+ return if (numCallableParameters == jsonParamValueList.size && valueCreator is ConstructorValueCreator ) {
161
124
// we didn't do anything special with default parameters, do a normal call
162
125
super .createFromObjectWith(ctxt, jsonParamValueList)
163
126
} 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
- }
127
+ valueCreator.checkAccessibility(ctxt)
128
+
170
129
val callableParametersByName = linkedMapOf<KParameter , Any ?>()
171
130
callableParameters.mapIndexed { idx, paramDef ->
172
131
if (paramDef != null ) {
173
132
callableParametersByName[paramDef] = jsonParamValueList[idx]
174
133
}
175
134
}
176
- callable .callBy(callableParametersByName)
135
+ valueCreator .callBy(callableParametersByName)
177
136
}
178
137
179
138
}
0 commit comments