Skip to content

Commit

Permalink
Variableize properties that are accessed many times
Browse files Browse the repository at this point in the history
  • Loading branch information
k163377 committed Jul 15, 2023
1 parent 075e133 commit e57dd11
Showing 1 changed file with 26 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import com.fasterxml.jackson.databind.exc.MismatchedInputException
import java.lang.reflect.TypeVariable
import kotlin.reflect.KParameter
import kotlin.reflect.KType
import kotlin.reflect.KTypeProjection
import kotlin.reflect.jvm.javaType

internal class KotlinValueInstantiator(
Expand All @@ -29,6 +30,8 @@ internal class KotlinValueInstantiator(

private fun KType.isGenericTypeVar() = javaType is TypeVariable<*>

private fun List<KTypeProjection>.markedNullableAt(index: Int) = getOrNull(index)?.type?.isMarkedNullable == false

override fun createFromObjectWith(
ctxt: DeserializationContext,
props: Array<out SettableBeanProperty>,
Expand Down Expand Up @@ -64,14 +67,15 @@ internal class KotlinValueInstantiator(
return@forEachIndexed
}

val paramType = paramDef.type
var paramVal = if (!isMissing || paramDef.isPrimitive() || jsonProp.hasInjectableValueId()) {
val tempParamVal = buffer.getParameter(jsonProp)
if (nullIsSameAsDefault && tempParamVal == null && paramDef.isOptional) {
return@forEachIndexed
}
tempParamVal
} else {
if(paramDef.type.isMarkedNullable) {
if(paramType.isMarkedNullable) {
// do not try to create any object if it is nullable and the value is missing
null
} else {
Expand All @@ -80,46 +84,51 @@ internal class KotlinValueInstantiator(
}
}

val propType = jsonProp.type

if (paramVal == null) {
if (jsonProp.type.requireEmptyValue()) {
if (propType.requireEmptyValue()) {
paramVal = NullsAsEmptyProvider(jsonProp.valueDeserializer).getNullValue(ctxt)
} else {
val isMissingAndRequired = isMissing && jsonProp.isRequired

// Since #310 reported that the calculation cost is high, isGenericTypeVar is determined last.
if (isMissingAndRequired || (!paramDef.type.isMarkedNullable && !paramDef.type.isGenericTypeVar())) {
if (isMissingAndRequired || (!paramType.isMarkedNullable && !paramType.isGenericTypeVar())) {
throw MismatchedInputException.from(
ctxt.parser,
jsonProp.type,
propType,
"Instantiation of $valueTypeDesc value failed for JSON property ${jsonProp.name} " +
"due to missing (therefore NULL) value for creator parameter ${paramDef.name} " +
"which is a non-nullable type"
).wrapWithPath(this.valueClass, jsonProp.name)
}
}
} else if (strictNullChecks) {
var paramType: String? = null
val arguments = paramType.arguments

var paramTypeStr: String? = null
var itemType: KType? = null
if (jsonProp.type.isCollectionLikeType && paramDef.type.arguments.getOrNull(0)?.type?.isMarkedNullable == false && (paramVal as Collection<*>).any { it == null }) {
paramType = "collection"
itemType = paramDef.type.arguments[0].type

if (propType.isCollectionLikeType && !arguments.markedNullableAt(0) && (paramVal as Collection<*>).any { it == null }) {
paramTypeStr = "collection"
itemType = arguments[0].type
}

if (jsonProp.type.isMapLikeType && paramDef.type.arguments.getOrNull(1)?.type?.isMarkedNullable == false && (paramVal as Map<*, *>).any { it.value == null }) {
paramType = "map"
itemType = paramDef.type.arguments[1].type
if (propType.isMapLikeType && !arguments.markedNullableAt(1) && (paramVal as Map<*, *>).any { it.value == null }) {
paramTypeStr = "map"
itemType = arguments[1].type
}

if (jsonProp.type.isArrayType && paramDef.type.arguments.getOrNull(0)?.type?.isMarkedNullable == false && (paramVal as Array<*>).any { it == null }) {
paramType = "array"
itemType = paramDef.type.arguments[0].type
if (propType.isArrayType && !arguments.markedNullableAt(0) && (paramVal as Array<*>).any { it == null }) {
paramTypeStr = "array"
itemType = arguments[0].type
}

if (paramType != null && itemType != null) {
if (paramTypeStr != null && itemType != null) {
throw MismatchedInputException.from(
ctxt.parser,
jsonProp.type,
"Instantiation of $itemType $paramType failed for JSON property ${jsonProp.name} due to null value in a $paramType that does not allow null values"
propType,
"Instantiation of $itemType $paramTypeStr failed for JSON property ${jsonProp.name} due to null value in a $paramTypeStr that does not allow null values"
).wrapWithPath(this.valueClass, jsonProp.name)
}
}
Expand Down

0 comments on commit e57dd11

Please sign in to comment.