11package org.utbot.fuzzer.providers
22
3+ import org.utbot.framework.plugin.api.ClassId
34import org.utbot.framework.plugin.api.UtArrayModel
5+ import org.utbot.framework.plugin.api.UtModel
6+ import org.utbot.framework.plugin.api.UtPrimitiveModel
47import org.utbot.framework.plugin.api.util.defaultValueModel
8+ import org.utbot.framework.plugin.api.util.intClassId
59import org.utbot.framework.plugin.api.util.isArray
610import org.utbot.fuzzer.FuzzedMethodDescription
7- import org.utbot.fuzzer.FuzzedParameter
8- import org.utbot.fuzzer.IdGenerator
9- import org.utbot.fuzzer.ModelProvider
10- import org.utbot.fuzzer.ModelProvider.Companion.yieldAllValues
11- import java.util.function.IntSupplier
11+ import org.utbot.fuzzer.IdentityPreservingIdGenerator
1212
1313class ArrayModelProvider (
14- private val idGenerator : IdGenerator <Int >
15- ) : ModelProvider {
16- override fun generate (description : FuzzedMethodDescription ): Sequence <FuzzedParameter > = sequence {
17- description.parametersMap
18- .asSequence()
19- .filter { (classId, _) -> classId.isArray }
20- .forEach { (arrayClassId, indices) ->
21- yieldAllValues(indices, listOf (0 , 10 ).map { arraySize ->
22- UtArrayModel (
23- id = idGenerator.createId(),
24- arrayClassId,
25- length = arraySize,
26- arrayClassId.elementClassId!! .defaultValueModel(),
27- mutableMapOf ()
28- ).fuzzed {
29- this .summary = " %var% = ${arrayClassId.elementClassId!! .simpleName} [$arraySize ]"
30- }
31- })
14+ idGenerator : IdentityPreservingIdGenerator <Int >,
15+ recursionDepthLeft : Int = 1
16+ ) : RecursiveModelProvider(idGenerator, recursionDepthLeft) {
17+ override fun createNewInstance (parentProvider : RecursiveModelProvider , newTotalLimit : Int ): RecursiveModelProvider =
18+ ArrayModelProvider (parentProvider.idGenerator, parentProvider.recursionDepthLeft - 1 )
19+ .copySettingsFrom(parentProvider)
20+ .apply {
21+ totalLimit = newTotalLimit
22+ if (parentProvider is ArrayModelProvider )
23+ branchingLimit = 1 // This improves performance but also forbids generating "jagged" arrays
3224 }
25+
26+ override fun generateModelConstructors (
27+ description : FuzzedMethodDescription ,
28+ classId : ClassId
29+ ): List <ModelConstructor > {
30+ if (! classId.isArray)
31+ return listOf ()
32+ val lengths = generateArrayLengths(description)
33+ return lengths.map { length ->
34+ ModelConstructor (List (length) { classId.elementClassId!! }) { values ->
35+ createFuzzedArrayModel(classId, length, values.map { it.model } )
36+ }
37+ }
38+ }
39+
40+ private fun generateArrayLengths (description : FuzzedMethodDescription ): List <Int > {
41+ val fuzzedLengths = fuzzValuesRecursively(
42+ types = listOf (intClassId),
43+ baseMethodDescription = description,
44+ modelProvider = ConstantsModelProvider
45+ )
46+
47+ // Firstly we will use most "interesting" default sizes, then we will use small sizes obtained from src
48+ return listOf (3 , 0 ) + fuzzedLengths
49+ .map { (it.single().model as UtPrimitiveModel ).value as Int }
50+ .filter { it in 1 .. 10 && it != 3 }
51+ .toSortedSet()
52+ .toList()
3353 }
54+
55+ private fun createFuzzedArrayModel (arrayClassId : ClassId , length : Int , values : List <UtModel >? ) =
56+ UtArrayModel (
57+ idGenerator.createId(),
58+ arrayClassId,
59+ length,
60+ arrayClassId.elementClassId!! .defaultValueModel(),
61+ values?.withIndex()?.associate { it.index to it.value }?.toMutableMap() ? : mutableMapOf ()
62+ ).fuzzed {
63+ this .summary = " %var% = ${arrayClassId.elementClassId!! .simpleName} [$length ]"
64+ }
3465}
0 commit comments