diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b3c85813..a8842f84 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -27,7 +27,8 @@ jobs: fail-fast: false matrix: java_version: ['8', '11', '17', '21'] - kotlin_version: ['1.7.22', '1.8.22', '1.9.21'] + # kotlin-reflect 1.8.2x has a bug and some tests fail, so we are downgrading to 1.8.10. + kotlin_version: ['1.7.22', '1.8.10', '1.9.22', '2.0.0-Beta2'] os: ['ubuntu-20.04'] env: JAVA_OPTS: "-XX:+TieredCompilation -XX:TieredStopAtLevel=1" diff --git a/release-notes/CREDITS-2.x b/release-notes/CREDITS-2.x index 914686e3..05f01ef3 100644 --- a/release-notes/CREDITS-2.x +++ b/release-notes/CREDITS-2.x @@ -18,6 +18,7 @@ Contributors: # 2.17.0 (not yet released) WrongWrong (@k163377) +* #755: Changes in constructor invocation and argument management. * #752: Fix KDoc for KotlinModule. * #751: Marked useKotlinPropertyNameForGetter as deprecated. * #747: Improved performance related to KotlinModule initialization and setupModule. diff --git a/release-notes/VERSION-2.x b/release-notes/VERSION-2.x index 7844687f..a08d7c26 100644 --- a/release-notes/VERSION-2.x +++ b/release-notes/VERSION-2.x @@ -18,6 +18,8 @@ Co-maintainers: 2.17.0 (not yet released) +#755: Changes in constructor invocation and argument management. + This change degrades performance in cases where the constructor is called without default arguments, but improves performance in other cases. #751: The KotlinModule#useKotlinPropertyNameForGetter property was deprecated because it differed from the name of the KotlinFeature. Please use KotlinModule#kotlinPropertyNameAsImplicitName from now on. #747: Improved performance related to KotlinModule initialization and setupModule. diff --git a/src/main/kotlin/tools/jackson/module/kotlin/ArgumentBucket.kt b/src/main/kotlin/tools/jackson/module/kotlin/ArgumentBucket.kt new file mode 100644 index 00000000..e3b63229 --- /dev/null +++ b/src/main/kotlin/tools/jackson/module/kotlin/ArgumentBucket.kt @@ -0,0 +1,68 @@ +package tools.jackson.module.kotlin + +import kotlin.reflect.KParameter + +internal class BucketGenerator private constructor(paramSize: Int, instanceParameter: KParameter?, instance: Any?) { + private val originalParameters = arrayOfNulls(paramSize) + private val originalArguments = arrayOfNulls(paramSize) + private val initialCount: Int + + init { + if (instance != null) { + originalParameters[0] = instanceParameter + originalArguments[0] = instance + initialCount = 1 + } else { + initialCount = 0 + } + } + + fun generate(): ArgumentBucket = ArgumentBucket( + parameters = originalParameters.clone(), + arguments = originalArguments.clone(), + count = initialCount + ) + + companion object { + fun forConstructor(paramSize: Int): BucketGenerator = BucketGenerator(paramSize, null, null) + + fun forMethod(paramSize: Int, instanceParameter: KParameter, instance: Any): BucketGenerator = + BucketGenerator(paramSize, instanceParameter, instance) + } +} + +internal class ArgumentBucket( + private val parameters: Array, + val arguments: Array, + private var count: Int +) : Map { + operator fun set(key: KParameter, value: Any?) { + arguments[key.index] = value + parameters[key.index] = key + + // Multiple calls are not checked because internally no calls are made more than once per argument. + count++ + } + + val isFullInitialized: Boolean get() = count == arguments.size + + private class Entry(override val key: KParameter, override val value: Any?) : Map.Entry + + override val entries: Set> + get() = parameters.mapNotNull { key -> key?.let { Entry(it, arguments[it.index]) } }.toSet() + override val keys: Set + get() = parameters.filterNotNull().toSet() + override val size: Int + get() = count + override val values: Collection + get() = keys.map { arguments[it.index] } + + override fun isEmpty(): Boolean = this.size == 0 + + // Skip the check here, as it is only called after the check for containsKey. + override fun get(key: KParameter): Any? = arguments[key.index] + + override fun containsValue(value: Any?): Boolean = keys.any { arguments[it.index] == value } + + override fun containsKey(key: KParameter): Boolean = parameters.any { it?.index == key.index } +} diff --git a/src/main/kotlin/tools/jackson/module/kotlin/ConstructorValueCreator.kt b/src/main/kotlin/tools/jackson/module/kotlin/ConstructorValueCreator.kt index 2fde3e66..222c996b 100644 --- a/src/main/kotlin/tools/jackson/module/kotlin/ConstructorValueCreator.kt +++ b/src/main/kotlin/tools/jackson/module/kotlin/ConstructorValueCreator.kt @@ -5,6 +5,7 @@ import kotlin.reflect.jvm.isAccessible internal class ConstructorValueCreator(override val callable: KFunction) : ValueCreator() { override val accessible: Boolean = callable.isAccessible + override val bucketGenerator: BucketGenerator = BucketGenerator.forConstructor(callable.parameters.size) init { // To prevent the call from failing, save the initial value and then rewrite the flag. diff --git a/src/main/kotlin/tools/jackson/module/kotlin/KotlinValueInstantiator.kt b/src/main/kotlin/tools/jackson/module/kotlin/KotlinValueInstantiator.kt index 6163f1e0..e589a300 100644 --- a/src/main/kotlin/tools/jackson/module/kotlin/KotlinValueInstantiator.kt +++ b/src/main/kotlin/tools/jackson/module/kotlin/KotlinValueInstantiator.kt @@ -42,24 +42,7 @@ internal class KotlinValueInstantiator( val valueCreator: ValueCreator<*> = cache.valueCreatorFromJava(_withArgsCreator) ?: return super.createFromObjectWith(ctxt, props, buffer) - val propCount: Int - var numCallableParameters: Int - val callableParameters: Array - val jsonParamValueList: Array - - if (valueCreator is MethodValueCreator) { - propCount = props.size + 1 - numCallableParameters = 1 - callableParameters = arrayOfNulls(propCount) - .apply { this[0] = valueCreator.instanceParameter } - jsonParamValueList = arrayOfNulls(propCount) - .apply { this[0] = valueCreator.companionObjectInstance } - } else { - propCount = props.size - numCallableParameters = 0 - callableParameters = arrayOfNulls(propCount) - jsonParamValueList = arrayOfNulls(propCount) - } + val bucket = valueCreator.generateBucket() valueCreator.valueParameters.forEachIndexed { idx, paramDef -> val jsonProp = props[idx] @@ -131,26 +114,12 @@ internal class KotlinValueInstantiator( } } - jsonParamValueList[numCallableParameters] = paramVal - callableParameters[numCallableParameters] = paramDef - numCallableParameters++ + bucket[paramDef] = paramVal } - return if (numCallableParameters == jsonParamValueList.size && valueCreator is ConstructorValueCreator) { - // we didn't do anything special with default parameters, do a normal call - super.createFromObjectWith(ctxt, jsonParamValueList) - } else { - valueCreator.checkAccessibility(ctxt) - - val callableParametersByName = linkedMapOf() - callableParameters.mapIndexed { idx, paramDef -> - if (paramDef != null) { - callableParametersByName[paramDef] = jsonParamValueList[idx] - } - } - valueCreator.callBy(callableParametersByName) - } + valueCreator.checkAccessibility(ctxt) + return valueCreator.callBy(bucket) } private fun SettableBeanProperty.hasInjectableValueId(): Boolean = injectableValueId != null diff --git a/src/main/kotlin/tools/jackson/module/kotlin/MethodValueCreator.kt b/src/main/kotlin/tools/jackson/module/kotlin/MethodValueCreator.kt index 40ab631a..8629f99b 100644 --- a/src/main/kotlin/tools/jackson/module/kotlin/MethodValueCreator.kt +++ b/src/main/kotlin/tools/jackson/module/kotlin/MethodValueCreator.kt @@ -9,9 +9,11 @@ import kotlin.reflect.jvm.isAccessible internal class MethodValueCreator private constructor( override val callable: KFunction, override val accessible: Boolean, - val companionObjectInstance: Any + companionObjectInstance: Any ) : ValueCreator() { - val instanceParameter: KParameter = callable.instanceParameter!! + override val bucketGenerator: BucketGenerator = callable.parameters.let { + BucketGenerator.forMethod(it.size, it[0], companionObjectInstance) + } companion object { fun of(callable: KFunction): MethodValueCreator? { diff --git a/src/main/kotlin/tools/jackson/module/kotlin/ValueCreator.kt b/src/main/kotlin/tools/jackson/module/kotlin/ValueCreator.kt index 5c54d042..8b61ec2a 100644 --- a/src/main/kotlin/tools/jackson/module/kotlin/ValueCreator.kt +++ b/src/main/kotlin/tools/jackson/module/kotlin/ValueCreator.kt @@ -21,6 +21,10 @@ internal sealed class ValueCreator { */ protected abstract val accessible: Boolean + protected abstract val bucketGenerator: BucketGenerator + + fun generateBucket(): ArgumentBucket = bucketGenerator.generate() + /** * ValueParameters of the KFunction to be called. */ @@ -45,5 +49,9 @@ internal sealed class ValueCreator { /** * Function call with default values enabled. */ - fun callBy(args: Map): T = callable.callBy(args) + fun callBy(args: ArgumentBucket): T = if (args.isFullInitialized) { + callable.call(*args.arguments) + } else { + callable.callBy(args) + } } diff --git a/src/test/kotlin/tools/jackson/module/kotlin/ArgumentBucketTest.kt b/src/test/kotlin/tools/jackson/module/kotlin/ArgumentBucketTest.kt new file mode 100644 index 00000000..20155690 --- /dev/null +++ b/src/test/kotlin/tools/jackson/module/kotlin/ArgumentBucketTest.kt @@ -0,0 +1,86 @@ +package com.fasterxml.jackson.module.kotlin + +import com.fasterxml.jackson.annotation.JsonCreator +import org.junit.Ignore +import org.junit.experimental.runners.Enclosed +import org.junit.runner.RunWith +import kotlin.reflect.KFunction +import kotlin.reflect.full.functions +import kotlin.reflect.full.hasAnnotation +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertTrue + + +@RunWith(Enclosed::class) +class ArgumentBucketTest { + class Normal { + @Ignore + data class Constructor(val foo: String, val bar: String) + + @Test + fun constructorTest() { + val function: KFunction<*> = ::Constructor + val params = function.parameters + val generator = BucketGenerator.forConstructor(params.size) + val bucket = generator.generate() + + assertTrue(bucket.isEmpty()) + assertEquals(0, bucket.size) + assertFalse(bucket.isFullInitialized) + + bucket[params[0]] = "foo" + + assertFalse(bucket.isEmpty()) + assertEquals(1, bucket.size) + assertFalse(bucket.isFullInitialized) + assertEquals("foo", bucket[params[0]]) + + bucket[params[1]] = "bar" + + assertFalse(bucket.isEmpty()) + assertEquals(2, bucket.size) + assertTrue(bucket.isFullInitialized) + assertEquals("bar", bucket[params[1]]) + } + + @Ignore + data class Method(val foo: String, val bar: String) { + companion object { + @JvmStatic + @JsonCreator + fun of(foo: String, bar: String): Method = Method(foo, bar) + } + } + + @Test + fun methodTest() { + val function: KFunction<*> = Method.Companion::class.functions.first { it.hasAnnotation() } + val params = function.parameters + val generator = BucketGenerator.forMethod(params.size, params[0], Method) + val bucket = generator.generate() + + assertFalse(bucket.isEmpty()) + assertEquals(1, bucket.size) + assertEquals(Method.Companion, bucket[params[0]]) + assertFalse(bucket.isFullInitialized) + + bucket[params[1]] = "foo" + + assertFalse(bucket.isEmpty()) + assertEquals(2, bucket.size) + assertFalse(bucket.isFullInitialized) + assertEquals("foo", bucket[params[1]]) + + bucket[params[2]] = "bar" + + assertFalse(bucket.isEmpty()) + assertEquals(3, bucket.size) + assertTrue(bucket.isFullInitialized) + assertEquals("bar", bucket[params[2]]) + } + } + + // After support, add a case with a value class. +} diff --git a/src/test/kotlin/tools/jackson/module/kotlin/TestCommons.kt b/src/test/kotlin/tools/jackson/module/kotlin/TestCommons.kt index ca053f5a..4a330fc6 100644 --- a/src/test/kotlin/tools/jackson/module/kotlin/TestCommons.kt +++ b/src/test/kotlin/tools/jackson/module/kotlin/TestCommons.kt @@ -5,6 +5,10 @@ import tools.jackson.core.util.DefaultIndenter import tools.jackson.core.util.DefaultPrettyPrinter import tools.jackson.databind.ObjectMapper import tools.jackson.databind.ObjectWriter +import kotlin.reflect.KParameter +import kotlin.reflect.full.memberProperties +import kotlin.reflect.full.primaryConstructor +import kotlin.test.assertEquals // This `printer` is used to match the output from Jackson to the newline char of the source code. // If this is removed, comparisons will fail in a Windows-like platform. @@ -12,3 +16,17 @@ val LF_PRINTER: PrettyPrinter = DefaultPrettyPrinter().withObjectIndenter(DefaultIndenter().withLinefeed("\n")) fun ObjectMapper.testPrettyWriter(): ObjectWriter = this.writer().with(LF_PRINTER) +internal val defaultMapper = jacksonObjectMapper() + +internal inline fun callPrimaryConstructor(mapper: (KParameter) -> Any? = { it.name }): T = + T::class.primaryConstructor!!.run { + val args = parameters.associateWith { mapper(it) } + callBy(args) + } + +// Function for comparing non-data classes. +internal inline fun assertReflectEquals(expected: T, actual: T) { + T::class.memberProperties.forEach { + assertEquals(it.get(expected), it.get(actual)) + } +} diff --git a/src/test/kotlin/tools/jackson/module/kotlin/test/parameterSize/DeserializeByConstructorWithDefaultArgumentsTest.kt b/src/test/kotlin/tools/jackson/module/kotlin/test/parameterSize/DeserializeByConstructorWithDefaultArgumentsTest.kt new file mode 100644 index 00000000..f3a11183 --- /dev/null +++ b/src/test/kotlin/tools/jackson/module/kotlin/test/parameterSize/DeserializeByConstructorWithDefaultArgumentsTest.kt @@ -0,0 +1,495 @@ +package tools.jackson.module.kotlin.test.parameterSize + +import tools.jackson.module.kotlin.assertReflectEquals +import tools.jackson.module.kotlin.defaultMapper +import tools.jackson.module.kotlin.readValue +import kotlin.test.Test +import kotlin.test.assertEquals + +/** + * Up to argument size 32 there is one mask argument for the default argument, + * 33 ~ 64 there are two, and 65 there are three, so each boundary value is tested. + * Also, if the default argument is set, the maximum argument size that can be set in the constructor is 245, + * so that case is tested as well. + */ +class DeserializeByConstructorWithDefaultArgumentsTest { + data class Dst32( + val p00: String = "0", + val p01: String = "1", + val p02: String = "2", + val p03: String = "3", + val p04: String = "4", + val p05: String = "5", + val p06: String = "6", + val p07: String = "7", + val p08: String = "8", + val p09: String = "9", + val p10: String = "10", + val p11: String = "11", + val p12: String = "12", + val p13: String = "13", + val p14: String = "14", + val p15: String = "15", + val p16: String = "16", + val p17: String = "17", + val p18: String = "18", + val p19: String = "19", + val p20: String = "20", + val p21: String = "21", + val p22: String = "22", + val p23: String = "23", + val p24: String = "24", + val p25: String = "25", + val p26: String = "26", + val p27: String = "27", + val p28: String = "28", + val p29: String = "29", + val p30: String = "30", + val p31: String = "31" + ) + + @Test + fun test32() { + assertEquals(Dst32(), defaultMapper.readValue("{}")) + } + + data class Dst33( + val p00: String = "0", + val p01: String = "1", + val p02: String = "2", + val p03: String = "3", + val p04: String = "4", + val p05: String = "5", + val p06: String = "6", + val p07: String = "7", + val p08: String = "8", + val p09: String = "9", + val p10: String = "10", + val p11: String = "11", + val p12: String = "12", + val p13: String = "13", + val p14: String = "14", + val p15: String = "15", + val p16: String = "16", + val p17: String = "17", + val p18: String = "18", + val p19: String = "19", + val p20: String = "20", + val p21: String = "21", + val p22: String = "22", + val p23: String = "23", + val p24: String = "24", + val p25: String = "25", + val p26: String = "26", + val p27: String = "27", + val p28: String = "28", + val p29: String = "29", + val p30: String = "30", + val p31: String = "31", + val p32: String = "32" + ) + + @Test + fun test33() { + assertEquals(Dst33(), defaultMapper.readValue("{}")) + } + + data class Dst64( + val p00: String = "0", + val p01: String = "1", + val p02: String = "2", + val p03: String = "3", + val p04: String = "4", + val p05: String = "5", + val p06: String = "6", + val p07: String = "7", + val p08: String = "8", + val p09: String = "9", + val p10: String = "10", + val p11: String = "11", + val p12: String = "12", + val p13: String = "13", + val p14: String = "14", + val p15: String = "15", + val p16: String = "16", + val p17: String = "17", + val p18: String = "18", + val p19: String = "19", + val p20: String = "20", + val p21: String = "21", + val p22: String = "22", + val p23: String = "23", + val p24: String = "24", + val p25: String = "25", + val p26: String = "26", + val p27: String = "27", + val p28: String = "28", + val p29: String = "29", + val p30: String = "30", + val p31: String = "31", + val p32: String = "32", + val p33: String = "33", + val p34: String = "34", + val p35: String = "35", + val p36: String = "36", + val p37: String = "37", + val p38: String = "38", + val p39: String = "39", + val p40: String = "40", + val p41: String = "41", + val p42: String = "42", + val p43: String = "43", + val p44: String = "44", + val p45: String = "45", + val p46: String = "46", + val p47: String = "47", + val p48: String = "48", + val p49: String = "49", + val p50: String = "50", + val p51: String = "51", + val p52: String = "52", + val p53: String = "53", + val p54: String = "54", + val p55: String = "55", + val p56: String = "56", + val p57: String = "57", + val p58: String = "58", + val p59: String = "59", + val p60: String = "60", + val p61: String = "61", + val p62: String = "62", + val p63: String = "63" + ) + + @Test + fun test64() { + assertEquals(Dst64(), defaultMapper.readValue("{}")) + } + + data class Dst65( + val p00: String = "0", + val p01: String = "1", + val p02: String = "2", + val p03: String = "3", + val p04: String = "4", + val p05: String = "5", + val p06: String = "6", + val p07: String = "7", + val p08: String = "8", + val p09: String = "9", + val p10: String = "10", + val p11: String = "11", + val p12: String = "12", + val p13: String = "13", + val p14: String = "14", + val p15: String = "15", + val p16: String = "16", + val p17: String = "17", + val p18: String = "18", + val p19: String = "19", + val p20: String = "20", + val p21: String = "21", + val p22: String = "22", + val p23: String = "23", + val p24: String = "24", + val p25: String = "25", + val p26: String = "26", + val p27: String = "27", + val p28: String = "28", + val p29: String = "29", + val p30: String = "30", + val p31: String = "31", + val p32: String = "32", + val p33: String = "33", + val p34: String = "34", + val p35: String = "35", + val p36: String = "36", + val p37: String = "37", + val p38: String = "38", + val p39: String = "39", + val p40: String = "40", + val p41: String = "41", + val p42: String = "42", + val p43: String = "43", + val p44: String = "44", + val p45: String = "45", + val p46: String = "46", + val p47: String = "47", + val p48: String = "48", + val p49: String = "49", + val p50: String = "50", + val p51: String = "51", + val p52: String = "52", + val p53: String = "53", + val p54: String = "54", + val p55: String = "55", + val p56: String = "56", + val p57: String = "57", + val p58: String = "58", + val p59: String = "59", + val p60: String = "60", + val p61: String = "61", + val p62: String = "62", + val p63: String = "63", + val p64: String = "64" + ) + + @Test + fun test65() { + assertEquals(Dst65(), defaultMapper.readValue("{}")) + } + + // It cannot be a data class because the generated method would exceed the argument size limit. + class DstMax( + val p000: String = "0", + val p001: String = "1", + val p002: String = "2", + val p003: String = "3", + val p004: String = "4", + val p005: String = "5", + val p006: String = "6", + val p007: String = "7", + val p008: String = "8", + val p009: String = "9", + val p010: String = "10", + val p011: String = "11", + val p012: String = "12", + val p013: String = "13", + val p014: String = "14", + val p015: String = "15", + val p016: String = "16", + val p017: String = "17", + val p018: String = "18", + val p019: String = "19", + val p020: String = "20", + val p021: String = "21", + val p022: String = "22", + val p023: String = "23", + val p024: String = "24", + val p025: String = "25", + val p026: String = "26", + val p027: String = "27", + val p028: String = "28", + val p029: String = "29", + val p030: String = "30", + val p031: String = "31", + val p032: String = "32", + val p033: String = "33", + val p034: String = "34", + val p035: String = "35", + val p036: String = "36", + val p037: String = "37", + val p038: String = "38", + val p039: String = "39", + val p040: String = "40", + val p041: String = "41", + val p042: String = "42", + val p043: String = "43", + val p044: String = "44", + val p045: String = "45", + val p046: String = "46", + val p047: String = "47", + val p048: String = "48", + val p049: String = "49", + val p050: String = "50", + val p051: String = "51", + val p052: String = "52", + val p053: String = "53", + val p054: String = "54", + val p055: String = "55", + val p056: String = "56", + val p057: String = "57", + val p058: String = "58", + val p059: String = "59", + val p060: String = "60", + val p061: String = "61", + val p062: String = "62", + val p063: String = "63", + val p064: String = "64", + val p065: String = "65", + val p066: String = "66", + val p067: String = "67", + val p068: String = "68", + val p069: String = "69", + val p070: String = "70", + val p071: String = "71", + val p072: String = "72", + val p073: String = "73", + val p074: String = "74", + val p075: String = "75", + val p076: String = "76", + val p077: String = "77", + val p078: String = "78", + val p079: String = "79", + val p080: String = "80", + val p081: String = "81", + val p082: String = "82", + val p083: String = "83", + val p084: String = "84", + val p085: String = "85", + val p086: String = "86", + val p087: String = "87", + val p088: String = "88", + val p089: String = "89", + val p090: String = "90", + val p091: String = "91", + val p092: String = "92", + val p093: String = "93", + val p094: String = "94", + val p095: String = "95", + val p096: String = "96", + val p097: String = "97", + val p098: String = "98", + val p099: String = "99", + val p100: String = "100", + val p101: String = "101", + val p102: String = "102", + val p103: String = "103", + val p104: String = "104", + val p105: String = "105", + val p106: String = "106", + val p107: String = "107", + val p108: String = "108", + val p109: String = "109", + val p110: String = "110", + val p111: String = "111", + val p112: String = "112", + val p113: String = "113", + val p114: String = "114", + val p115: String = "115", + val p116: String = "116", + val p117: String = "117", + val p118: String = "118", + val p119: String = "119", + val p120: String = "120", + val p121: String = "121", + val p122: String = "122", + val p123: String = "123", + val p124: String = "124", + val p125: String = "125", + val p126: String = "126", + val p127: String = "127", + val p128: String = "128", + val p129: String = "129", + val p130: String = "130", + val p131: String = "131", + val p132: String = "132", + val p133: String = "133", + val p134: String = "134", + val p135: String = "135", + val p136: String = "136", + val p137: String = "137", + val p138: String = "138", + val p139: String = "139", + val p140: String = "140", + val p141: String = "141", + val p142: String = "142", + val p143: String = "143", + val p144: String = "144", + val p145: String = "145", + val p146: String = "146", + val p147: String = "147", + val p148: String = "148", + val p149: String = "149", + val p150: String = "150", + val p151: String = "151", + val p152: String = "152", + val p153: String = "153", + val p154: String = "154", + val p155: String = "155", + val p156: String = "156", + val p157: String = "157", + val p158: String = "158", + val p159: String = "159", + val p160: String = "160", + val p161: String = "161", + val p162: String = "162", + val p163: String = "163", + val p164: String = "164", + val p165: String = "165", + val p166: String = "166", + val p167: String = "167", + val p168: String = "168", + val p169: String = "169", + val p170: String = "170", + val p171: String = "171", + val p172: String = "172", + val p173: String = "173", + val p174: String = "174", + val p175: String = "175", + val p176: String = "176", + val p177: String = "177", + val p178: String = "178", + val p179: String = "179", + val p180: String = "180", + val p181: String = "181", + val p182: String = "182", + val p183: String = "183", + val p184: String = "184", + val p185: String = "185", + val p186: String = "186", + val p187: String = "187", + val p188: String = "188", + val p189: String = "189", + val p190: String = "190", + val p191: String = "191", + val p192: String = "192", + val p193: String = "193", + val p194: String = "194", + val p195: String = "195", + val p196: String = "196", + val p197: String = "197", + val p198: String = "198", + val p199: String = "199", + val p200: String = "200", + val p201: String = "201", + val p202: String = "202", + val p203: String = "203", + val p204: String = "204", + val p205: String = "205", + val p206: String = "206", + val p207: String = "207", + val p208: String = "208", + val p209: String = "209", + val p210: String = "210", + val p211: String = "211", + val p212: String = "212", + val p213: String = "213", + val p214: String = "214", + val p215: String = "215", + val p216: String = "216", + val p217: String = "217", + val p218: String = "218", + val p219: String = "219", + val p220: String = "220", + val p221: String = "221", + val p222: String = "222", + val p223: String = "223", + val p224: String = "224", + val p225: String = "225", + val p226: String = "226", + val p227: String = "227", + val p228: String = "228", + val p229: String = "229", + val p230: String = "230", + val p231: String = "231", + val p232: String = "232", + val p233: String = "233", + val p234: String = "234", + val p235: String = "235", + val p236: String = "236", + val p237: String = "237", + val p238: String = "238", + val p239: String = "239", + val p240: String = "240", + val p241: String = "241", + val p242: String = "242", + val p243: String = "243", + val p244: String = "244" + ) + + @Test + fun testMax() { + assertReflectEquals(DstMax(), defaultMapper.readValue("{}")) + } +} diff --git a/src/test/kotlin/tools/jackson/module/kotlin/test/parameterSize/DeserializeByConstructorWithoutDefaultArgumentsTest.kt b/src/test/kotlin/tools/jackson/module/kotlin/test/parameterSize/DeserializeByConstructorWithoutDefaultArgumentsTest.kt new file mode 100644 index 00000000..c1d7a78a --- /dev/null +++ b/src/test/kotlin/tools/jackson/module/kotlin/test/parameterSize/DeserializeByConstructorWithoutDefaultArgumentsTest.kt @@ -0,0 +1,514 @@ +package tools.jackson.module.kotlin.test.parameterSize + +import tools.jackson.module.kotlin.assertReflectEquals +import tools.jackson.module.kotlin.callPrimaryConstructor +import tools.jackson.module.kotlin.defaultMapper +import tools.jackson.module.kotlin.readValue +import kotlin.test.Test +import kotlin.test.assertEquals + +/** + * Up to argument size 32 there is one mask argument for the default argument, + * 33 ~ 64 there are two, and 65 there are three, so each boundary value is tested. + * Also, the maximum argument size that can be set in the constructor is 254, so that case is tested as well. + */ +class DeserializeByConstructorWithoutDefaultArgumentsTest { + data class Dst32( + val p00: String, + val p01: String, + val p02: String, + val p03: String, + val p04: String, + val p05: String, + val p06: String, + val p07: String, + val p08: String, + val p09: String, + val p10: String, + val p11: String, + val p12: String, + val p13: String, + val p14: String, + val p15: String, + val p16: String, + val p17: String, + val p18: String, + val p19: String, + val p20: String, + val p21: String, + val p22: String, + val p23: String, + val p24: String, + val p25: String, + val p26: String, + val p27: String, + val p28: String, + val p29: String, + val p30: String, + val p31: String + ) + + @Test + fun test32() { + val expected = callPrimaryConstructor() + val src = defaultMapper.writeValueAsString(expected) + assertEquals(expected, defaultMapper.readValue(src)) + } + + data class Dst33( + val p00: String, + val p01: String, + val p02: String, + val p03: String, + val p04: String, + val p05: String, + val p06: String, + val p07: String, + val p08: String, + val p09: String, + val p10: String, + val p11: String, + val p12: String, + val p13: String, + val p14: String, + val p15: String, + val p16: String, + val p17: String, + val p18: String, + val p19: String, + val p20: String, + val p21: String, + val p22: String, + val p23: String, + val p24: String, + val p25: String, + val p26: String, + val p27: String, + val p28: String, + val p29: String, + val p30: String, + val p31: String, + val p32: String + ) + + @Test + fun test33() { + val expected = callPrimaryConstructor() + val src = defaultMapper.writeValueAsString(expected) + assertEquals(expected, defaultMapper.readValue(src)) + } + + data class Dst64( + val p00: String, + val p01: String, + val p02: String, + val p03: String, + val p04: String, + val p05: String, + val p06: String, + val p07: String, + val p08: String, + val p09: String, + val p10: String, + val p11: String, + val p12: String, + val p13: String, + val p14: String, + val p15: String, + val p16: String, + val p17: String, + val p18: String, + val p19: String, + val p20: String, + val p21: String, + val p22: String, + val p23: String, + val p24: String, + val p25: String, + val p26: String, + val p27: String, + val p28: String, + val p29: String, + val p30: String, + val p31: String, + val p32: String, + val p33: String, + val p34: String, + val p35: String, + val p36: String, + val p37: String, + val p38: String, + val p39: String, + val p40: String, + val p41: String, + val p42: String, + val p43: String, + val p44: String, + val p45: String, + val p46: String, + val p47: String, + val p48: String, + val p49: String, + val p50: String, + val p51: String, + val p52: String, + val p53: String, + val p54: String, + val p55: String, + val p56: String, + val p57: String, + val p58: String, + val p59: String, + val p60: String, + val p61: String, + val p62: String, + val p63: String + ) + + @Test + fun test64() { + val expected = callPrimaryConstructor() + val src = defaultMapper.writeValueAsString(expected) + assertEquals(expected, defaultMapper.readValue(src)) + } + + data class Dst65( + val p00: String, + val p01: String, + val p02: String, + val p03: String, + val p04: String, + val p05: String, + val p06: String, + val p07: String, + val p08: String, + val p09: String, + val p10: String, + val p11: String, + val p12: String, + val p13: String, + val p14: String, + val p15: String, + val p16: String, + val p17: String, + val p18: String, + val p19: String, + val p20: String, + val p21: String, + val p22: String, + val p23: String, + val p24: String, + val p25: String, + val p26: String, + val p27: String, + val p28: String, + val p29: String, + val p30: String, + val p31: String, + val p32: String, + val p33: String, + val p34: String, + val p35: String, + val p36: String, + val p37: String, + val p38: String, + val p39: String, + val p40: String, + val p41: String, + val p42: String, + val p43: String, + val p44: String, + val p45: String, + val p46: String, + val p47: String, + val p48: String, + val p49: String, + val p50: String, + val p51: String, + val p52: String, + val p53: String, + val p54: String, + val p55: String, + val p56: String, + val p57: String, + val p58: String, + val p59: String, + val p60: String, + val p61: String, + val p62: String, + val p63: String, + val p64: String + ) + + @Test + fun test65() { + val expected = callPrimaryConstructor() + val src = defaultMapper.writeValueAsString(expected) + assertEquals(expected, defaultMapper.readValue(src)) + } + + // It cannot be a data class because the generated method would exceed the argument size limit. + class DstMax( + val p000: String, + val p001: String, + val p002: String, + val p003: String, + val p004: String, + val p005: String, + val p006: String, + val p007: String, + val p008: String, + val p009: String, + val p010: String, + val p011: String, + val p012: String, + val p013: String, + val p014: String, + val p015: String, + val p016: String, + val p017: String, + val p018: String, + val p019: String, + val p020: String, + val p021: String, + val p022: String, + val p023: String, + val p024: String, + val p025: String, + val p026: String, + val p027: String, + val p028: String, + val p029: String, + val p030: String, + val p031: String, + val p032: String, + val p033: String, + val p034: String, + val p035: String, + val p036: String, + val p037: String, + val p038: String, + val p039: String, + val p040: String, + val p041: String, + val p042: String, + val p043: String, + val p044: String, + val p045: String, + val p046: String, + val p047: String, + val p048: String, + val p049: String, + val p050: String, + val p051: String, + val p052: String, + val p053: String, + val p054: String, + val p055: String, + val p056: String, + val p057: String, + val p058: String, + val p059: String, + val p060: String, + val p061: String, + val p062: String, + val p063: String, + val p064: String, + val p065: String, + val p066: String, + val p067: String, + val p068: String, + val p069: String, + val p070: String, + val p071: String, + val p072: String, + val p073: String, + val p074: String, + val p075: String, + val p076: String, + val p077: String, + val p078: String, + val p079: String, + val p080: String, + val p081: String, + val p082: String, + val p083: String, + val p084: String, + val p085: String, + val p086: String, + val p087: String, + val p088: String, + val p089: String, + val p090: String, + val p091: String, + val p092: String, + val p093: String, + val p094: String, + val p095: String, + val p096: String, + val p097: String, + val p098: String, + val p099: String, + val p100: String, + val p101: String, + val p102: String, + val p103: String, + val p104: String, + val p105: String, + val p106: String, + val p107: String, + val p108: String, + val p109: String, + val p110: String, + val p111: String, + val p112: String, + val p113: String, + val p114: String, + val p115: String, + val p116: String, + val p117: String, + val p118: String, + val p119: String, + val p120: String, + val p121: String, + val p122: String, + val p123: String, + val p124: String, + val p125: String, + val p126: String, + val p127: String, + val p128: String, + val p129: String, + val p130: String, + val p131: String, + val p132: String, + val p133: String, + val p134: String, + val p135: String, + val p136: String, + val p137: String, + val p138: String, + val p139: String, + val p140: String, + val p141: String, + val p142: String, + val p143: String, + val p144: String, + val p145: String, + val p146: String, + val p147: String, + val p148: String, + val p149: String, + val p150: String, + val p151: String, + val p152: String, + val p153: String, + val p154: String, + val p155: String, + val p156: String, + val p157: String, + val p158: String, + val p159: String, + val p160: String, + val p161: String, + val p162: String, + val p163: String, + val p164: String, + val p165: String, + val p166: String, + val p167: String, + val p168: String, + val p169: String, + val p170: String, + val p171: String, + val p172: String, + val p173: String, + val p174: String, + val p175: String, + val p176: String, + val p177: String, + val p178: String, + val p179: String, + val p180: String, + val p181: String, + val p182: String, + val p183: String, + val p184: String, + val p185: String, + val p186: String, + val p187: String, + val p188: String, + val p189: String, + val p190: String, + val p191: String, + val p192: String, + val p193: String, + val p194: String, + val p195: String, + val p196: String, + val p197: String, + val p198: String, + val p199: String, + val p200: String, + val p201: String, + val p202: String, + val p203: String, + val p204: String, + val p205: String, + val p206: String, + val p207: String, + val p208: String, + val p209: String, + val p210: String, + val p211: String, + val p212: String, + val p213: String, + val p214: String, + val p215: String, + val p216: String, + val p217: String, + val p218: String, + val p219: String, + val p220: String, + val p221: String, + val p222: String, + val p223: String, + val p224: String, + val p225: String, + val p226: String, + val p227: String, + val p228: String, + val p229: String, + val p230: String, + val p231: String, + val p232: String, + val p233: String, + val p234: String, + val p235: String, + val p236: String, + val p237: String, + val p238: String, + val p239: String, + val p240: String, + val p241: String, + val p242: String, + val p243: String, + val p244: String, + val p245: String, + val p246: String, + val p247: String, + val p248: String, + val p249: String, + val p250: String, + val p251: String, + val p252: String, + val p253: String + ) + + @Test + fun testMax() { + val expected = callPrimaryConstructor() + val src = defaultMapper.writeValueAsString(expected) + assertReflectEquals(expected, defaultMapper.readValue(src)) + } +} diff --git a/src/test/kotlin/tools/jackson/module/kotlin/test/parameterSize/DeserializeByFactoryWithDefaultArgumentsTest.kt b/src/test/kotlin/tools/jackson/module/kotlin/test/parameterSize/DeserializeByFactoryWithDefaultArgumentsTest.kt new file mode 100644 index 00000000..af5d6f5c --- /dev/null +++ b/src/test/kotlin/tools/jackson/module/kotlin/test/parameterSize/DeserializeByFactoryWithDefaultArgumentsTest.kt @@ -0,0 +1,1410 @@ +package tools.jackson.module.kotlin.test.parameterSize + +import com.fasterxml.jackson.annotation.JsonCreator +import tools.jackson.module.kotlin.assertReflectEquals +import tools.jackson.module.kotlin.defaultMapper +import tools.jackson.module.kotlin.readValue +import kotlin.test.Test +import kotlin.test.assertEquals + +/** + * Up to argument size 32 there is one mask argument for the default argument, + * 33 ~ 64 there are two, and 65 there are three, so each boundary value is tested. + * Also, the maximum argument size that can be set in the constructor is 244, so that case is tested as well. + */ +class DeserializeByFactoryWithDefaultArgumentsTest { + data class Dst32( + val p00: String, + val p01: String, + val p02: String, + val p03: String, + val p04: String, + val p05: String, + val p06: String, + val p07: String, + val p08: String, + val p09: String, + val p10: String, + val p11: String, + val p12: String, + val p13: String, + val p14: String, + val p15: String, + val p16: String, + val p17: String, + val p18: String, + val p19: String, + val p20: String, + val p21: String, + val p22: String, + val p23: String, + val p24: String, + val p25: String, + val p26: String, + val p27: String, + val p28: String, + val p29: String, + val p30: String, + val p31: String + ) { + companion object { + @JvmStatic + @JsonCreator + fun creator( + q00: String = "p00", + q01: String = "p01", + q02: String = "p02", + q03: String = "p03", + q04: String = "p04", + q05: String = "p05", + q06: String = "p06", + q07: String = "p07", + q08: String = "p08", + q09: String = "p09", + q10: String = "p10", + q11: String = "p11", + q12: String = "p12", + q13: String = "p13", + q14: String = "p14", + q15: String = "p15", + q16: String = "p16", + q17: String = "p17", + q18: String = "p18", + q19: String = "p19", + q20: String = "p20", + q21: String = "p21", + q22: String = "p22", + q23: String = "p23", + q24: String = "p24", + q25: String = "p25", + q26: String = "p26", + q27: String = "p27", + q28: String = "p28", + q29: String = "p29", + q30: String = "p30", + q31: String = "p31" + ) = Dst32( + q00, + q01, + q02, + q03, + q04, + q05, + q06, + q07, + q08, + q09, + q10, + q11, + q12, + q13, + q14, + q15, + q16, + q17, + q18, + q19, + q20, + q21, + q22, + q23, + q24, + q25, + q26, + q27, + q28, + q29, + q30, + q31 + ) + } + } + + @Test + fun test32() { + assertEquals(Dst32.creator(), defaultMapper.readValue("{}")) + } + + data class Dst33( + val p00: String, + val p01: String, + val p02: String, + val p03: String, + val p04: String, + val p05: String, + val p06: String, + val p07: String, + val p08: String, + val p09: String, + val p10: String, + val p11: String, + val p12: String, + val p13: String, + val p14: String, + val p15: String, + val p16: String, + val p17: String, + val p18: String, + val p19: String, + val p20: String, + val p21: String, + val p22: String, + val p23: String, + val p24: String, + val p25: String, + val p26: String, + val p27: String, + val p28: String, + val p29: String, + val p30: String, + val p31: String, + val p32: String + ) { + companion object { + @JvmStatic + @JsonCreator + fun creator( + q00: String = "p00", + q01: String = "p01", + q02: String = "p02", + q03: String = "p03", + q04: String = "p04", + q05: String = "p05", + q06: String = "p06", + q07: String = "p07", + q08: String = "p08", + q09: String = "p09", + q10: String = "p10", + q11: String = "p11", + q12: String = "p12", + q13: String = "p13", + q14: String = "p14", + q15: String = "p15", + q16: String = "p16", + q17: String = "p17", + q18: String = "p18", + q19: String = "p19", + q20: String = "p20", + q21: String = "p21", + q22: String = "p22", + q23: String = "p23", + q24: String = "p24", + q25: String = "p25", + q26: String = "p26", + q27: String = "p27", + q28: String = "p28", + q29: String = "p29", + q30: String = "p30", + q31: String = "p31", + q32: String = "p32" + ) = Dst33( + q00, + q01, + q02, + q03, + q04, + q05, + q06, + q07, + q08, + q09, + q10, + q11, + q12, + q13, + q14, + q15, + q16, + q17, + q18, + q19, + q20, + q21, + q22, + q23, + q24, + q25, + q26, + q27, + q28, + q29, + q30, + q31, + q32 + ) + } + } + + @Test + fun test33() { + assertEquals(Dst33.creator(), defaultMapper.readValue("{}")) + } + + data class Dst64( + val p00: String, + val p01: String, + val p02: String, + val p03: String, + val p04: String, + val p05: String, + val p06: String, + val p07: String, + val p08: String, + val p09: String, + val p10: String, + val p11: String, + val p12: String, + val p13: String, + val p14: String, + val p15: String, + val p16: String, + val p17: String, + val p18: String, + val p19: String, + val p20: String, + val p21: String, + val p22: String, + val p23: String, + val p24: String, + val p25: String, + val p26: String, + val p27: String, + val p28: String, + val p29: String, + val p30: String, + val p31: String, + val p32: String, + val p33: String, + val p34: String, + val p35: String, + val p36: String, + val p37: String, + val p38: String, + val p39: String, + val p40: String, + val p41: String, + val p42: String, + val p43: String, + val p44: String, + val p45: String, + val p46: String, + val p47: String, + val p48: String, + val p49: String, + val p50: String, + val p51: String, + val p52: String, + val p53: String, + val p54: String, + val p55: String, + val p56: String, + val p57: String, + val p58: String, + val p59: String, + val p60: String, + val p61: String, + val p62: String, + val p63: String + ) { + companion object { + @JvmStatic + @JsonCreator + fun creator( + q00: String = "p00", + q01: String = "p01", + q02: String = "p02", + q03: String = "p03", + q04: String = "p04", + q05: String = "p05", + q06: String = "p06", + q07: String = "p07", + q08: String = "p08", + q09: String = "p09", + q10: String = "p10", + q11: String = "p11", + q12: String = "p12", + q13: String = "p13", + q14: String = "p14", + q15: String = "p15", + q16: String = "p16", + q17: String = "p17", + q18: String = "p18", + q19: String = "p19", + q20: String = "p20", + q21: String = "p21", + q22: String = "p22", + q23: String = "p23", + q24: String = "p24", + q25: String = "p25", + q26: String = "p26", + q27: String = "p27", + q28: String = "p28", + q29: String = "p29", + q30: String = "p30", + q31: String = "p31", + q32: String = "p32", + q33: String = "p33", + q34: String = "p34", + q35: String = "p35", + q36: String = "p36", + q37: String = "p37", + q38: String = "p38", + q39: String = "p39", + q40: String = "p40", + q41: String = "p41", + q42: String = "p42", + q43: String = "p43", + q44: String = "p44", + q45: String = "p45", + q46: String = "p46", + q47: String = "p47", + q48: String = "p48", + q49: String = "p49", + q50: String = "p50", + q51: String = "p51", + q52: String = "p52", + q53: String = "p53", + q54: String = "p54", + q55: String = "p55", + q56: String = "p56", + q57: String = "p57", + q58: String = "p58", + q59: String = "p59", + q60: String = "p60", + q61: String = "p61", + q62: String = "p62", + q63: String = "p63" + ) = Dst64( + q00, + q01, + q02, + q03, + q04, + q05, + q06, + q07, + q08, + q09, + q10, + q11, + q12, + q13, + q14, + q15, + q16, + q17, + q18, + q19, + q20, + q21, + q22, + q23, + q24, + q25, + q26, + q27, + q28, + q29, + q30, + q31, + q32, + q33, + q34, + q35, + q36, + q37, + q38, + q39, + q40, + q41, + q42, + q43, + q44, + q45, + q46, + q47, + q48, + q49, + q50, + q51, + q52, + q53, + q54, + q55, + q56, + q57, + q58, + q59, + q60, + q61, + q62, + q63 + ) + } + } + + @Test + fun test64() { + assertEquals(Dst64.creator(), defaultMapper.readValue("{}")) + } + + data class Dst65( + val p00: String, + val p01: String, + val p02: String, + val p03: String, + val p04: String, + val p05: String, + val p06: String, + val p07: String, + val p08: String, + val p09: String, + val p10: String, + val p11: String, + val p12: String, + val p13: String, + val p14: String, + val p15: String, + val p16: String, + val p17: String, + val p18: String, + val p19: String, + val p20: String, + val p21: String, + val p22: String, + val p23: String, + val p24: String, + val p25: String, + val p26: String, + val p27: String, + val p28: String, + val p29: String, + val p30: String, + val p31: String, + val p32: String, + val p33: String, + val p34: String, + val p35: String, + val p36: String, + val p37: String, + val p38: String, + val p39: String, + val p40: String, + val p41: String, + val p42: String, + val p43: String, + val p44: String, + val p45: String, + val p46: String, + val p47: String, + val p48: String, + val p49: String, + val p50: String, + val p51: String, + val p52: String, + val p53: String, + val p54: String, + val p55: String, + val p56: String, + val p57: String, + val p58: String, + val p59: String, + val p60: String, + val p61: String, + val p62: String, + val p63: String, + val p64: String + ) { + companion object { + @JvmStatic + @JsonCreator + fun creator( + q00: String = "p00", + q01: String = "p01", + q02: String = "p02", + q03: String = "p03", + q04: String = "p04", + q05: String = "p05", + q06: String = "p06", + q07: String = "p07", + q08: String = "p08", + q09: String = "p09", + q10: String = "p10", + q11: String = "p11", + q12: String = "p12", + q13: String = "p13", + q14: String = "p14", + q15: String = "p15", + q16: String = "p16", + q17: String = "p17", + q18: String = "p18", + q19: String = "p19", + q20: String = "p20", + q21: String = "p21", + q22: String = "p22", + q23: String = "p23", + q24: String = "p24", + q25: String = "p25", + q26: String = "p26", + q27: String = "p27", + q28: String = "p28", + q29: String = "p29", + q30: String = "p30", + q31: String = "p31", + q32: String = "p32", + q33: String = "p33", + q34: String = "p34", + q35: String = "p35", + q36: String = "p36", + q37: String = "p37", + q38: String = "p38", + q39: String = "p39", + q40: String = "p40", + q41: String = "p41", + q42: String = "p42", + q43: String = "p43", + q44: String = "p44", + q45: String = "p45", + q46: String = "p46", + q47: String = "p47", + q48: String = "p48", + q49: String = "p49", + q50: String = "p50", + q51: String = "p51", + q52: String = "p52", + q53: String = "p53", + q54: String = "p54", + q55: String = "p55", + q56: String = "p56", + q57: String = "p57", + q58: String = "p58", + q59: String = "p59", + q60: String = "p60", + q61: String = "p61", + q62: String = "p62", + q63: String = "p63", + q64: String = "p64" + ) = Dst65( + q00, + q01, + q02, + q03, + q04, + q05, + q06, + q07, + q08, + q09, + q10, + q11, + q12, + q13, + q14, + q15, + q16, + q17, + q18, + q19, + q20, + q21, + q22, + q23, + q24, + q25, + q26, + q27, + q28, + q29, + q30, + q31, + q32, + q33, + q34, + q35, + q36, + q37, + q38, + q39, + q40, + q41, + q42, + q43, + q44, + q45, + q46, + q47, + q48, + q49, + q50, + q51, + q52, + q53, + q54, + q55, + q56, + q57, + q58, + q59, + q60, + q61, + q62, + q63, + q64 + ) + } + } + + @Test + fun test65() { + assertEquals(Dst65.creator(), defaultMapper.readValue("{}")) + } + + // It cannot be a data class because the generated method would exceed the argument size limit. + class DstMax( + val p000: String, + val p001: String, + val p002: String, + val p003: String, + val p004: String, + val p005: String, + val p006: String, + val p007: String, + val p008: String, + val p009: String, + val p010: String, + val p011: String, + val p012: String, + val p013: String, + val p014: String, + val p015: String, + val p016: String, + val p017: String, + val p018: String, + val p019: String, + val p020: String, + val p021: String, + val p022: String, + val p023: String, + val p024: String, + val p025: String, + val p026: String, + val p027: String, + val p028: String, + val p029: String, + val p030: String, + val p031: String, + val p032: String, + val p033: String, + val p034: String, + val p035: String, + val p036: String, + val p037: String, + val p038: String, + val p039: String, + val p040: String, + val p041: String, + val p042: String, + val p043: String, + val p044: String, + val p045: String, + val p046: String, + val p047: String, + val p048: String, + val p049: String, + val p050: String, + val p051: String, + val p052: String, + val p053: String, + val p054: String, + val p055: String, + val p056: String, + val p057: String, + val p058: String, + val p059: String, + val p060: String, + val p061: String, + val p062: String, + val p063: String, + val p064: String, + val p065: String, + val p066: String, + val p067: String, + val p068: String, + val p069: String, + val p070: String, + val p071: String, + val p072: String, + val p073: String, + val p074: String, + val p075: String, + val p076: String, + val p077: String, + val p078: String, + val p079: String, + val p080: String, + val p081: String, + val p082: String, + val p083: String, + val p084: String, + val p085: String, + val p086: String, + val p087: String, + val p088: String, + val p089: String, + val p090: String, + val p091: String, + val p092: String, + val p093: String, + val p094: String, + val p095: String, + val p096: String, + val p097: String, + val p098: String, + val p099: String, + val p100: String, + val p101: String, + val p102: String, + val p103: String, + val p104: String, + val p105: String, + val p106: String, + val p107: String, + val p108: String, + val p109: String, + val p110: String, + val p111: String, + val p112: String, + val p113: String, + val p114: String, + val p115: String, + val p116: String, + val p117: String, + val p118: String, + val p119: String, + val p120: String, + val p121: String, + val p122: String, + val p123: String, + val p124: String, + val p125: String, + val p126: String, + val p127: String, + val p128: String, + val p129: String, + val p130: String, + val p131: String, + val p132: String, + val p133: String, + val p134: String, + val p135: String, + val p136: String, + val p137: String, + val p138: String, + val p139: String, + val p140: String, + val p141: String, + val p142: String, + val p143: String, + val p144: String, + val p145: String, + val p146: String, + val p147: String, + val p148: String, + val p149: String, + val p150: String, + val p151: String, + val p152: String, + val p153: String, + val p154: String, + val p155: String, + val p156: String, + val p157: String, + val p158: String, + val p159: String, + val p160: String, + val p161: String, + val p162: String, + val p163: String, + val p164: String, + val p165: String, + val p166: String, + val p167: String, + val p168: String, + val p169: String, + val p170: String, + val p171: String, + val p172: String, + val p173: String, + val p174: String, + val p175: String, + val p176: String, + val p177: String, + val p178: String, + val p179: String, + val p180: String, + val p181: String, + val p182: String, + val p183: String, + val p184: String, + val p185: String, + val p186: String, + val p187: String, + val p188: String, + val p189: String, + val p190: String, + val p191: String, + val p192: String, + val p193: String, + val p194: String, + val p195: String, + val p196: String, + val p197: String, + val p198: String, + val p199: String, + val p200: String, + val p201: String, + val p202: String, + val p203: String, + val p204: String, + val p205: String, + val p206: String, + val p207: String, + val p208: String, + val p209: String, + val p210: String, + val p211: String, + val p212: String, + val p213: String, + val p214: String, + val p215: String, + val p216: String, + val p217: String, + val p218: String, + val p219: String, + val p220: String, + val p221: String, + val p222: String, + val p223: String, + val p224: String, + val p225: String, + val p226: String, + val p227: String, + val p228: String, + val p229: String, + val p230: String, + val p231: String, + val p232: String, + val p233: String, + val p234: String, + val p235: String, + val p236: String, + val p237: String, + val p238: String, + val p239: String, + val p240: String, + val p241: String, + val p242: String, + val p243: String + ) { + companion object { + @JvmStatic + @JsonCreator + fun creator( + q000: String = "p000", + q001: String = "p001", + q002: String = "p002", + q003: String = "p003", + q004: String = "p004", + q005: String = "p005", + q006: String = "p006", + q007: String = "p007", + q008: String = "p008", + q009: String = "p009", + q010: String = "p010", + q011: String = "p011", + q012: String = "p012", + q013: String = "p013", + q014: String = "p014", + q015: String = "p015", + q016: String = "p016", + q017: String = "p017", + q018: String = "p018", + q019: String = "p019", + q020: String = "p020", + q021: String = "p021", + q022: String = "p022", + q023: String = "p023", + q024: String = "p024", + q025: String = "p025", + q026: String = "p026", + q027: String = "p027", + q028: String = "p028", + q029: String = "p029", + q030: String = "p030", + q031: String = "p031", + q032: String = "p032", + q033: String = "p033", + q034: String = "p034", + q035: String = "p035", + q036: String = "p036", + q037: String = "p037", + q038: String = "p038", + q039: String = "p039", + q040: String = "p040", + q041: String = "p041", + q042: String = "p042", + q043: String = "p043", + q044: String = "p044", + q045: String = "p045", + q046: String = "p046", + q047: String = "p047", + q048: String = "p048", + q049: String = "p049", + q050: String = "p050", + q051: String = "p051", + q052: String = "p052", + q053: String = "p053", + q054: String = "p054", + q055: String = "p055", + q056: String = "p056", + q057: String = "p057", + q058: String = "p058", + q059: String = "p059", + q060: String = "p060", + q061: String = "p061", + q062: String = "p062", + q063: String = "p063", + q064: String = "p064", + q065: String = "p065", + q066: String = "p066", + q067: String = "p067", + q068: String = "p068", + q069: String = "p069", + q070: String = "p070", + q071: String = "p071", + q072: String = "p072", + q073: String = "p073", + q074: String = "p074", + q075: String = "p075", + q076: String = "p076", + q077: String = "p077", + q078: String = "p078", + q079: String = "p079", + q080: String = "p080", + q081: String = "p081", + q082: String = "p082", + q083: String = "p083", + q084: String = "p084", + q085: String = "p085", + q086: String = "p086", + q087: String = "p087", + q088: String = "p088", + q089: String = "p089", + q090: String = "p090", + q091: String = "p091", + q092: String = "p092", + q093: String = "p093", + q094: String = "p094", + q095: String = "p095", + q096: String = "p096", + q097: String = "p097", + q098: String = "p098", + q099: String = "p099", + q100: String = "p100", + q101: String = "p101", + q102: String = "p102", + q103: String = "p103", + q104: String = "p104", + q105: String = "p105", + q106: String = "p106", + q107: String = "p107", + q108: String = "p108", + q109: String = "p109", + q110: String = "p110", + q111: String = "p111", + q112: String = "p112", + q113: String = "p113", + q114: String = "p114", + q115: String = "p115", + q116: String = "p116", + q117: String = "p117", + q118: String = "p118", + q119: String = "p119", + q120: String = "p120", + q121: String = "p121", + q122: String = "p122", + q123: String = "p123", + q124: String = "p124", + q125: String = "p125", + q126: String = "p126", + q127: String = "p127", + q128: String = "p128", + q129: String = "p129", + q130: String = "p130", + q131: String = "p131", + q132: String = "p132", + q133: String = "p133", + q134: String = "p134", + q135: String = "p135", + q136: String = "p136", + q137: String = "p137", + q138: String = "p138", + q139: String = "p139", + q140: String = "p140", + q141: String = "p141", + q142: String = "p142", + q143: String = "p143", + q144: String = "p144", + q145: String = "p145", + q146: String = "p146", + q147: String = "p147", + q148: String = "p148", + q149: String = "p149", + q150: String = "p150", + q151: String = "p151", + q152: String = "p152", + q153: String = "p153", + q154: String = "p154", + q155: String = "p155", + q156: String = "p156", + q157: String = "p157", + q158: String = "p158", + q159: String = "p159", + q160: String = "p160", + q161: String = "p161", + q162: String = "p162", + q163: String = "p163", + q164: String = "p164", + q165: String = "p165", + q166: String = "p166", + q167: String = "p167", + q168: String = "p168", + q169: String = "p169", + q170: String = "p170", + q171: String = "p171", + q172: String = "p172", + q173: String = "p173", + q174: String = "p174", + q175: String = "p175", + q176: String = "p176", + q177: String = "p177", + q178: String = "p178", + q179: String = "p179", + q180: String = "p180", + q181: String = "p181", + q182: String = "p182", + q183: String = "p183", + q184: String = "p184", + q185: String = "p185", + q186: String = "p186", + q187: String = "p187", + q188: String = "p188", + q189: String = "p189", + q190: String = "p190", + q191: String = "p191", + q192: String = "p192", + q193: String = "p193", + q194: String = "p194", + q195: String = "p195", + q196: String = "p196", + q197: String = "p197", + q198: String = "p198", + q199: String = "p199", + q200: String = "p200", + q201: String = "p201", + q202: String = "p202", + q203: String = "p203", + q204: String = "p204", + q205: String = "p205", + q206: String = "p206", + q207: String = "p207", + q208: String = "p208", + q209: String = "p209", + q210: String = "p210", + q211: String = "p211", + q212: String = "p212", + q213: String = "p213", + q214: String = "p214", + q215: String = "p215", + q216: String = "p216", + q217: String = "p217", + q218: String = "p218", + q219: String = "p219", + q220: String = "p220", + q221: String = "p221", + q222: String = "p222", + q223: String = "p223", + q224: String = "p224", + q225: String = "p225", + q226: String = "p226", + q227: String = "p227", + q228: String = "p228", + q229: String = "p229", + q230: String = "p230", + q231: String = "p231", + q232: String = "p232", + q233: String = "p233", + q234: String = "p234", + q235: String = "p235", + q236: String = "p236", + q237: String = "p237", + q238: String = "p238", + q239: String = "p239", + q240: String = "p240", + q241: String = "p241", + q242: String = "p242", + q243: String = "p243" + ) = DstMax( + q000, + q001, + q002, + q003, + q004, + q005, + q006, + q007, + q008, + q009, + q010, + q011, + q012, + q013, + q014, + q015, + q016, + q017, + q018, + q019, + q020, + q021, + q022, + q023, + q024, + q025, + q026, + q027, + q028, + q029, + q030, + q031, + q032, + q033, + q034, + q035, + q036, + q037, + q038, + q039, + q040, + q041, + q042, + q043, + q044, + q045, + q046, + q047, + q048, + q049, + q050, + q051, + q052, + q053, + q054, + q055, + q056, + q057, + q058, + q059, + q060, + q061, + q062, + q063, + q064, + q065, + q066, + q067, + q068, + q069, + q070, + q071, + q072, + q073, + q074, + q075, + q076, + q077, + q078, + q079, + q080, + q081, + q082, + q083, + q084, + q085, + q086, + q087, + q088, + q089, + q090, + q091, + q092, + q093, + q094, + q095, + q096, + q097, + q098, + q099, + q100, + q101, + q102, + q103, + q104, + q105, + q106, + q107, + q108, + q109, + q110, + q111, + q112, + q113, + q114, + q115, + q116, + q117, + q118, + q119, + q120, + q121, + q122, + q123, + q124, + q125, + q126, + q127, + q128, + q129, + q130, + q131, + q132, + q133, + q134, + q135, + q136, + q137, + q138, + q139, + q140, + q141, + q142, + q143, + q144, + q145, + q146, + q147, + q148, + q149, + q150, + q151, + q152, + q153, + q154, + q155, + q156, + q157, + q158, + q159, + q160, + q161, + q162, + q163, + q164, + q165, + q166, + q167, + q168, + q169, + q170, + q171, + q172, + q173, + q174, + q175, + q176, + q177, + q178, + q179, + q180, + q181, + q182, + q183, + q184, + q185, + q186, + q187, + q188, + q189, + q190, + q191, + q192, + q193, + q194, + q195, + q196, + q197, + q198, + q199, + q200, + q201, + q202, + q203, + q204, + q205, + q206, + q207, + q208, + q209, + q210, + q211, + q212, + q213, + q214, + q215, + q216, + q217, + q218, + q219, + q220, + q221, + q222, + q223, + q224, + q225, + q226, + q227, + q228, + q229, + q230, + q231, + q232, + q233, + q234, + q235, + q236, + q237, + q238, + q239, + q240, + q241, + q242, + q243 + ) + } + } + + @Test + fun testMax() { + assertReflectEquals(DstMax.creator(), defaultMapper.readValue("{}")) + } +} diff --git a/src/test/kotlin/tools/jackson/module/kotlin/test/parameterSize/DeserializeByFactoryWithoutDefaultArgumentsTest.kt b/src/test/kotlin/tools/jackson/module/kotlin/test/parameterSize/DeserializeByFactoryWithoutDefaultArgumentsTest.kt new file mode 100644 index 00000000..16699aff --- /dev/null +++ b/src/test/kotlin/tools/jackson/module/kotlin/test/parameterSize/DeserializeByFactoryWithoutDefaultArgumentsTest.kt @@ -0,0 +1,1454 @@ +package tools.jackson.module.kotlin.test.parameterSize + +import com.fasterxml.jackson.annotation.JsonCreator +import tools.jackson.module.kotlin.assertReflectEquals +import tools.jackson.module.kotlin.callPrimaryConstructor +import tools.jackson.module.kotlin.defaultMapper +import tools.jackson.module.kotlin.readValue +import kotlin.test.Test +import kotlin.test.assertEquals + +// Convert the property p to q (but not the value) to make it an input to the factory function. +private fun replacePQ(src: String) = src.replace(Regex("""p\d+":""")) { "q" + it.value.substring(1) } + +/** + * Up to argument size 32 there is one mask argument for the default argument, + * 33 ~ 64 there are two, and 65 there are three, so each boundary value is tested. + * Also, the maximum argument size that can be set in the constructor is 254, so that case is tested as well. + */ +class DeserializeByFactoryWithoutDefaultArgumentsTest { + data class Dst32( + val p00: String, + val p01: String, + val p02: String, + val p03: String, + val p04: String, + val p05: String, + val p06: String, + val p07: String, + val p08: String, + val p09: String, + val p10: String, + val p11: String, + val p12: String, + val p13: String, + val p14: String, + val p15: String, + val p16: String, + val p17: String, + val p18: String, + val p19: String, + val p20: String, + val p21: String, + val p22: String, + val p23: String, + val p24: String, + val p25: String, + val p26: String, + val p27: String, + val p28: String, + val p29: String, + val p30: String, + val p31: String + ) { + companion object { + @JvmStatic + @JsonCreator + fun creator( + q00: String, + q01: String, + q02: String, + q03: String, + q04: String, + q05: String, + q06: String, + q07: String, + q08: String, + q09: String, + q10: String, + q11: String, + q12: String, + q13: String, + q14: String, + q15: String, + q16: String, + q17: String, + q18: String, + q19: String, + q20: String, + q21: String, + q22: String, + q23: String, + q24: String, + q25: String, + q26: String, + q27: String, + q28: String, + q29: String, + q30: String, + q31: String + ) = Dst32( + q00, + q01, + q02, + q03, + q04, + q05, + q06, + q07, + q08, + q09, + q10, + q11, + q12, + q13, + q14, + q15, + q16, + q17, + q18, + q19, + q20, + q21, + q22, + q23, + q24, + q25, + q26, + q27, + q28, + q29, + q30, + q31 + ) + } + } + + @Test + fun test32() { + val expected = callPrimaryConstructor() + val src = replacePQ(defaultMapper.writeValueAsString(expected)) + assertEquals(expected, defaultMapper.readValue(src)) + } + + data class Dst33( + val p00: String, + val p01: String, + val p02: String, + val p03: String, + val p04: String, + val p05: String, + val p06: String, + val p07: String, + val p08: String, + val p09: String, + val p10: String, + val p11: String, + val p12: String, + val p13: String, + val p14: String, + val p15: String, + val p16: String, + val p17: String, + val p18: String, + val p19: String, + val p20: String, + val p21: String, + val p22: String, + val p23: String, + val p24: String, + val p25: String, + val p26: String, + val p27: String, + val p28: String, + val p29: String, + val p30: String, + val p31: String, + val p32: String + ) { + companion object { + @JvmStatic + @JsonCreator + fun creator( + q00: String, + q01: String, + q02: String, + q03: String, + q04: String, + q05: String, + q06: String, + q07: String, + q08: String, + q09: String, + q10: String, + q11: String, + q12: String, + q13: String, + q14: String, + q15: String, + q16: String, + q17: String, + q18: String, + q19: String, + q20: String, + q21: String, + q22: String, + q23: String, + q24: String, + q25: String, + q26: String, + q27: String, + q28: String, + q29: String, + q30: String, + q31: String, + q32: String + ) = Dst33( + q00, + q01, + q02, + q03, + q04, + q05, + q06, + q07, + q08, + q09, + q10, + q11, + q12, + q13, + q14, + q15, + q16, + q17, + q18, + q19, + q20, + q21, + q22, + q23, + q24, + q25, + q26, + q27, + q28, + q29, + q30, + q31, + q32 + ) + } + } + + @Test + fun test33() { + val expected = callPrimaryConstructor() + val src = replacePQ(defaultMapper.writeValueAsString(expected)) + assertEquals(expected, defaultMapper.readValue(src)) + } + + data class Dst64( + val p00: String, + val p01: String, + val p02: String, + val p03: String, + val p04: String, + val p05: String, + val p06: String, + val p07: String, + val p08: String, + val p09: String, + val p10: String, + val p11: String, + val p12: String, + val p13: String, + val p14: String, + val p15: String, + val p16: String, + val p17: String, + val p18: String, + val p19: String, + val p20: String, + val p21: String, + val p22: String, + val p23: String, + val p24: String, + val p25: String, + val p26: String, + val p27: String, + val p28: String, + val p29: String, + val p30: String, + val p31: String, + val p32: String, + val p33: String, + val p34: String, + val p35: String, + val p36: String, + val p37: String, + val p38: String, + val p39: String, + val p40: String, + val p41: String, + val p42: String, + val p43: String, + val p44: String, + val p45: String, + val p46: String, + val p47: String, + val p48: String, + val p49: String, + val p50: String, + val p51: String, + val p52: String, + val p53: String, + val p54: String, + val p55: String, + val p56: String, + val p57: String, + val p58: String, + val p59: String, + val p60: String, + val p61: String, + val p62: String, + val p63: String + ) { + companion object { + @JvmStatic + @JsonCreator + fun creator( + q00: String, + q01: String, + q02: String, + q03: String, + q04: String, + q05: String, + q06: String, + q07: String, + q08: String, + q09: String, + q10: String, + q11: String, + q12: String, + q13: String, + q14: String, + q15: String, + q16: String, + q17: String, + q18: String, + q19: String, + q20: String, + q21: String, + q22: String, + q23: String, + q24: String, + q25: String, + q26: String, + q27: String, + q28: String, + q29: String, + q30: String, + q31: String, + q32: String, + q33: String, + q34: String, + q35: String, + q36: String, + q37: String, + q38: String, + q39: String, + q40: String, + q41: String, + q42: String, + q43: String, + q44: String, + q45: String, + q46: String, + q47: String, + q48: String, + q49: String, + q50: String, + q51: String, + q52: String, + q53: String, + q54: String, + q55: String, + q56: String, + q57: String, + q58: String, + q59: String, + q60: String, + q61: String, + q62: String, + q63: String + ) = Dst64( + q00, + q01, + q02, + q03, + q04, + q05, + q06, + q07, + q08, + q09, + q10, + q11, + q12, + q13, + q14, + q15, + q16, + q17, + q18, + q19, + q20, + q21, + q22, + q23, + q24, + q25, + q26, + q27, + q28, + q29, + q30, + q31, + q32, + q33, + q34, + q35, + q36, + q37, + q38, + q39, + q40, + q41, + q42, + q43, + q44, + q45, + q46, + q47, + q48, + q49, + q50, + q51, + q52, + q53, + q54, + q55, + q56, + q57, + q58, + q59, + q60, + q61, + q62, + q63 + ) + } + } + + @Test + fun test64() { + val expected = callPrimaryConstructor() + val src = replacePQ(defaultMapper.writeValueAsString(expected)) + assertEquals(expected, defaultMapper.readValue(src)) + } + + data class Dst65( + val p00: String, + val p01: String, + val p02: String, + val p03: String, + val p04: String, + val p05: String, + val p06: String, + val p07: String, + val p08: String, + val p09: String, + val p10: String, + val p11: String, + val p12: String, + val p13: String, + val p14: String, + val p15: String, + val p16: String, + val p17: String, + val p18: String, + val p19: String, + val p20: String, + val p21: String, + val p22: String, + val p23: String, + val p24: String, + val p25: String, + val p26: String, + val p27: String, + val p28: String, + val p29: String, + val p30: String, + val p31: String, + val p32: String, + val p33: String, + val p34: String, + val p35: String, + val p36: String, + val p37: String, + val p38: String, + val p39: String, + val p40: String, + val p41: String, + val p42: String, + val p43: String, + val p44: String, + val p45: String, + val p46: String, + val p47: String, + val p48: String, + val p49: String, + val p50: String, + val p51: String, + val p52: String, + val p53: String, + val p54: String, + val p55: String, + val p56: String, + val p57: String, + val p58: String, + val p59: String, + val p60: String, + val p61: String, + val p62: String, + val p63: String, + val p64: String + ) { + companion object { + @JvmStatic + @JsonCreator + fun creator( + q00: String, + q01: String, + q02: String, + q03: String, + q04: String, + q05: String, + q06: String, + q07: String, + q08: String, + q09: String, + q10: String, + q11: String, + q12: String, + q13: String, + q14: String, + q15: String, + q16: String, + q17: String, + q18: String, + q19: String, + q20: String, + q21: String, + q22: String, + q23: String, + q24: String, + q25: String, + q26: String, + q27: String, + q28: String, + q29: String, + q30: String, + q31: String, + q32: String, + q33: String, + q34: String, + q35: String, + q36: String, + q37: String, + q38: String, + q39: String, + q40: String, + q41: String, + q42: String, + q43: String, + q44: String, + q45: String, + q46: String, + q47: String, + q48: String, + q49: String, + q50: String, + q51: String, + q52: String, + q53: String, + q54: String, + q55: String, + q56: String, + q57: String, + q58: String, + q59: String, + q60: String, + q61: String, + q62: String, + q63: String, + q64: String + ) = Dst65( + q00, + q01, + q02, + q03, + q04, + q05, + q06, + q07, + q08, + q09, + q10, + q11, + q12, + q13, + q14, + q15, + q16, + q17, + q18, + q19, + q20, + q21, + q22, + q23, + q24, + q25, + q26, + q27, + q28, + q29, + q30, + q31, + q32, + q33, + q34, + q35, + q36, + q37, + q38, + q39, + q40, + q41, + q42, + q43, + q44, + q45, + q46, + q47, + q48, + q49, + q50, + q51, + q52, + q53, + q54, + q55, + q56, + q57, + q58, + q59, + q60, + q61, + q62, + q63, + q64 + ) + } + } + + @Test + fun test65() { + val expected = callPrimaryConstructor() + val src = replacePQ(defaultMapper.writeValueAsString(expected)) + assertEquals(expected, defaultMapper.readValue(src)) + } + + // It cannot be a data class because the generated method would exceed the argument size limit. + class DstMax( + val p000: String, + val p001: String, + val p002: String, + val p003: String, + val p004: String, + val p005: String, + val p006: String, + val p007: String, + val p008: String, + val p009: String, + val p010: String, + val p011: String, + val p012: String, + val p013: String, + val p014: String, + val p015: String, + val p016: String, + val p017: String, + val p018: String, + val p019: String, + val p020: String, + val p021: String, + val p022: String, + val p023: String, + val p024: String, + val p025: String, + val p026: String, + val p027: String, + val p028: String, + val p029: String, + val p030: String, + val p031: String, + val p032: String, + val p033: String, + val p034: String, + val p035: String, + val p036: String, + val p037: String, + val p038: String, + val p039: String, + val p040: String, + val p041: String, + val p042: String, + val p043: String, + val p044: String, + val p045: String, + val p046: String, + val p047: String, + val p048: String, + val p049: String, + val p050: String, + val p051: String, + val p052: String, + val p053: String, + val p054: String, + val p055: String, + val p056: String, + val p057: String, + val p058: String, + val p059: String, + val p060: String, + val p061: String, + val p062: String, + val p063: String, + val p064: String, + val p065: String, + val p066: String, + val p067: String, + val p068: String, + val p069: String, + val p070: String, + val p071: String, + val p072: String, + val p073: String, + val p074: String, + val p075: String, + val p076: String, + val p077: String, + val p078: String, + val p079: String, + val p080: String, + val p081: String, + val p082: String, + val p083: String, + val p084: String, + val p085: String, + val p086: String, + val p087: String, + val p088: String, + val p089: String, + val p090: String, + val p091: String, + val p092: String, + val p093: String, + val p094: String, + val p095: String, + val p096: String, + val p097: String, + val p098: String, + val p099: String, + val p100: String, + val p101: String, + val p102: String, + val p103: String, + val p104: String, + val p105: String, + val p106: String, + val p107: String, + val p108: String, + val p109: String, + val p110: String, + val p111: String, + val p112: String, + val p113: String, + val p114: String, + val p115: String, + val p116: String, + val p117: String, + val p118: String, + val p119: String, + val p120: String, + val p121: String, + val p122: String, + val p123: String, + val p124: String, + val p125: String, + val p126: String, + val p127: String, + val p128: String, + val p129: String, + val p130: String, + val p131: String, + val p132: String, + val p133: String, + val p134: String, + val p135: String, + val p136: String, + val p137: String, + val p138: String, + val p139: String, + val p140: String, + val p141: String, + val p142: String, + val p143: String, + val p144: String, + val p145: String, + val p146: String, + val p147: String, + val p148: String, + val p149: String, + val p150: String, + val p151: String, + val p152: String, + val p153: String, + val p154: String, + val p155: String, + val p156: String, + val p157: String, + val p158: String, + val p159: String, + val p160: String, + val p161: String, + val p162: String, + val p163: String, + val p164: String, + val p165: String, + val p166: String, + val p167: String, + val p168: String, + val p169: String, + val p170: String, + val p171: String, + val p172: String, + val p173: String, + val p174: String, + val p175: String, + val p176: String, + val p177: String, + val p178: String, + val p179: String, + val p180: String, + val p181: String, + val p182: String, + val p183: String, + val p184: String, + val p185: String, + val p186: String, + val p187: String, + val p188: String, + val p189: String, + val p190: String, + val p191: String, + val p192: String, + val p193: String, + val p194: String, + val p195: String, + val p196: String, + val p197: String, + val p198: String, + val p199: String, + val p200: String, + val p201: String, + val p202: String, + val p203: String, + val p204: String, + val p205: String, + val p206: String, + val p207: String, + val p208: String, + val p209: String, + val p210: String, + val p211: String, + val p212: String, + val p213: String, + val p214: String, + val p215: String, + val p216: String, + val p217: String, + val p218: String, + val p219: String, + val p220: String, + val p221: String, + val p222: String, + val p223: String, + val p224: String, + val p225: String, + val p226: String, + val p227: String, + val p228: String, + val p229: String, + val p230: String, + val p231: String, + val p232: String, + val p233: String, + val p234: String, + val p235: String, + val p236: String, + val p237: String, + val p238: String, + val p239: String, + val p240: String, + val p241: String, + val p242: String, + val p243: String, + val p244: String, + val p245: String, + val p246: String, + val p247: String, + val p248: String, + val p249: String, + val p250: String, + val p251: String, + val p252: String, + val p253: String + ) { + companion object { + @JvmStatic + @JsonCreator + fun creator( + q000: String, + q001: String, + q002: String, + q003: String, + q004: String, + q005: String, + q006: String, + q007: String, + q008: String, + q009: String, + q010: String, + q011: String, + q012: String, + q013: String, + q014: String, + q015: String, + q016: String, + q017: String, + q018: String, + q019: String, + q020: String, + q021: String, + q022: String, + q023: String, + q024: String, + q025: String, + q026: String, + q027: String, + q028: String, + q029: String, + q030: String, + q031: String, + q032: String, + q033: String, + q034: String, + q035: String, + q036: String, + q037: String, + q038: String, + q039: String, + q040: String, + q041: String, + q042: String, + q043: String, + q044: String, + q045: String, + q046: String, + q047: String, + q048: String, + q049: String, + q050: String, + q051: String, + q052: String, + q053: String, + q054: String, + q055: String, + q056: String, + q057: String, + q058: String, + q059: String, + q060: String, + q061: String, + q062: String, + q063: String, + q064: String, + q065: String, + q066: String, + q067: String, + q068: String, + q069: String, + q070: String, + q071: String, + q072: String, + q073: String, + q074: String, + q075: String, + q076: String, + q077: String, + q078: String, + q079: String, + q080: String, + q081: String, + q082: String, + q083: String, + q084: String, + q085: String, + q086: String, + q087: String, + q088: String, + q089: String, + q090: String, + q091: String, + q092: String, + q093: String, + q094: String, + q095: String, + q096: String, + q097: String, + q098: String, + q099: String, + q100: String, + q101: String, + q102: String, + q103: String, + q104: String, + q105: String, + q106: String, + q107: String, + q108: String, + q109: String, + q110: String, + q111: String, + q112: String, + q113: String, + q114: String, + q115: String, + q116: String, + q117: String, + q118: String, + q119: String, + q120: String, + q121: String, + q122: String, + q123: String, + q124: String, + q125: String, + q126: String, + q127: String, + q128: String, + q129: String, + q130: String, + q131: String, + q132: String, + q133: String, + q134: String, + q135: String, + q136: String, + q137: String, + q138: String, + q139: String, + q140: String, + q141: String, + q142: String, + q143: String, + q144: String, + q145: String, + q146: String, + q147: String, + q148: String, + q149: String, + q150: String, + q151: String, + q152: String, + q153: String, + q154: String, + q155: String, + q156: String, + q157: String, + q158: String, + q159: String, + q160: String, + q161: String, + q162: String, + q163: String, + q164: String, + q165: String, + q166: String, + q167: String, + q168: String, + q169: String, + q170: String, + q171: String, + q172: String, + q173: String, + q174: String, + q175: String, + q176: String, + q177: String, + q178: String, + q179: String, + q180: String, + q181: String, + q182: String, + q183: String, + q184: String, + q185: String, + q186: String, + q187: String, + q188: String, + q189: String, + q190: String, + q191: String, + q192: String, + q193: String, + q194: String, + q195: String, + q196: String, + q197: String, + q198: String, + q199: String, + q200: String, + q201: String, + q202: String, + q203: String, + q204: String, + q205: String, + q206: String, + q207: String, + q208: String, + q209: String, + q210: String, + q211: String, + q212: String, + q213: String, + q214: String, + q215: String, + q216: String, + q217: String, + q218: String, + q219: String, + q220: String, + q221: String, + q222: String, + q223: String, + q224: String, + q225: String, + q226: String, + q227: String, + q228: String, + q229: String, + q230: String, + q231: String, + q232: String, + q233: String, + q234: String, + q235: String, + q236: String, + q237: String, + q238: String, + q239: String, + q240: String, + q241: String, + q242: String, + q243: String, + q244: String, + q245: String, + q246: String, + q247: String, + q248: String, + q249: String, + q250: String, + q251: String, + q252: String, + q253: String + ) = DstMax( + q000, + q001, + q002, + q003, + q004, + q005, + q006, + q007, + q008, + q009, + q010, + q011, + q012, + q013, + q014, + q015, + q016, + q017, + q018, + q019, + q020, + q021, + q022, + q023, + q024, + q025, + q026, + q027, + q028, + q029, + q030, + q031, + q032, + q033, + q034, + q035, + q036, + q037, + q038, + q039, + q040, + q041, + q042, + q043, + q044, + q045, + q046, + q047, + q048, + q049, + q050, + q051, + q052, + q053, + q054, + q055, + q056, + q057, + q058, + q059, + q060, + q061, + q062, + q063, + q064, + q065, + q066, + q067, + q068, + q069, + q070, + q071, + q072, + q073, + q074, + q075, + q076, + q077, + q078, + q079, + q080, + q081, + q082, + q083, + q084, + q085, + q086, + q087, + q088, + q089, + q090, + q091, + q092, + q093, + q094, + q095, + q096, + q097, + q098, + q099, + q100, + q101, + q102, + q103, + q104, + q105, + q106, + q107, + q108, + q109, + q110, + q111, + q112, + q113, + q114, + q115, + q116, + q117, + q118, + q119, + q120, + q121, + q122, + q123, + q124, + q125, + q126, + q127, + q128, + q129, + q130, + q131, + q132, + q133, + q134, + q135, + q136, + q137, + q138, + q139, + q140, + q141, + q142, + q143, + q144, + q145, + q146, + q147, + q148, + q149, + q150, + q151, + q152, + q153, + q154, + q155, + q156, + q157, + q158, + q159, + q160, + q161, + q162, + q163, + q164, + q165, + q166, + q167, + q168, + q169, + q170, + q171, + q172, + q173, + q174, + q175, + q176, + q177, + q178, + q179, + q180, + q181, + q182, + q183, + q184, + q185, + q186, + q187, + q188, + q189, + q190, + q191, + q192, + q193, + q194, + q195, + q196, + q197, + q198, + q199, + q200, + q201, + q202, + q203, + q204, + q205, + q206, + q207, + q208, + q209, + q210, + q211, + q212, + q213, + q214, + q215, + q216, + q217, + q218, + q219, + q220, + q221, + q222, + q223, + q224, + q225, + q226, + q227, + q228, + q229, + q230, + q231, + q232, + q233, + q234, + q235, + q236, + q237, + q238, + q239, + q240, + q241, + q242, + q243, + q244, + q245, + q246, + q247, + q248, + q249, + q250, + q251, + q252, + q253 + ) + } + } + + @Test + fun testMax() { + val expected = callPrimaryConstructor() + val src = replacePQ(defaultMapper.writeValueAsString(expected)) + assertReflectEquals(expected, defaultMapper.readValue(src)) + } +}