@@ -2,62 +2,54 @@ package org.utbot.fuzzer.providers
2
2
3
3
import org.utbot.framework.plugin.api.ClassId
4
4
import org.utbot.framework.plugin.api.UtArrayModel
5
+ import org.utbot.framework.plugin.api.UtModel
5
6
import org.utbot.framework.plugin.api.UtPrimitiveModel
6
7
import org.utbot.framework.plugin.api.util.defaultValueModel
7
8
import org.utbot.framework.plugin.api.util.intClassId
8
9
import org.utbot.framework.plugin.api.util.isArray
9
- import org.utbot.framework.plugin.api.util.voidClassId
10
10
import org.utbot.fuzzer.FuzzedMethodDescription
11
11
import org.utbot.fuzzer.FuzzedParameter
12
12
import org.utbot.fuzzer.FuzzedValue
13
13
import org.utbot.fuzzer.IdentityPreservingIdGenerator
14
- import org.utbot.fuzzer.ModelProvider
15
14
import org.utbot.fuzzer.ModelProvider.Companion.yieldAllValues
16
- import org.utbot.fuzzer.defaultModelProviders
17
- import org.utbot.fuzzer.fuzz
18
15
19
16
class ArrayModelProvider (
20
- private val idGenerator : IdentityPreservingIdGenerator <Int >
21
- ) : ModelProvider {
17
+ idGenerator : IdentityPreservingIdGenerator <Int >,
18
+ recursion : Int = 1
19
+ ) : RecursiveModelProvider(idGenerator, recursion) {
22
20
23
- private val defaultArraySize: Int = 3
21
+ private val defaultArraySize: Int
22
+ get() = when (recursion) {
23
+ 1 -> 3
24
+ else -> 1
25
+ }
24
26
25
27
override fun generate (description : FuzzedMethodDescription ): Sequence <FuzzedParameter > = sequence {
26
28
description.parametersMap
27
29
.asSequence()
28
30
.filter { (classId, _) -> classId.isArray }
29
31
.forEach { (arrayClassId, indices) ->
30
- val lengths = generateArrayLengths(description)
31
32
32
33
// Fuzz small arrays with interesting elements
33
34
yieldAllValues(indices, generateArrayRecursively(arrayClassId, description, defaultArraySize))
34
35
35
36
// Fuzz arrays with interesting lengths and default-valued elements
37
+ val lengths = generateArrayLengths(description)
36
38
yieldAllValues(indices, lengths.asSequence().map { length ->
37
- UtArrayModel (
38
- id = idGenerator.createId(),
39
- arrayClassId,
40
- length = length,
41
- arrayClassId.elementClassId!! .defaultValueModel(),
42
- mutableMapOf ()
43
- ).fuzzed {
44
- this .summary = " %var% = ${arrayClassId.elementClassId!! .simpleName} [$length ]"
45
- }
39
+ createFuzzedArrayModel(arrayClassId, length, null )
46
40
})
47
41
}
48
42
}
49
43
50
44
private fun generateArrayLengths (description : FuzzedMethodDescription ): Set <Int > {
51
- val syntheticArrayLengthMethodDescription = FuzzedMethodDescription (
52
- " <syntheticArrayLength>" ,
53
- voidClassId,
54
- listOf (intClassId),
55
- description.concreteValues
56
- ).apply {
57
- packageName = description.packageName
58
- }
45
+ val fuzzedLengths = fuzzValuesRecursively(
46
+ types = listOf (intClassId),
47
+ baseMethodDescription = description,
48
+ modelProvider = ConstantsModelProvider ,
49
+ generatedValuesName = " array length"
50
+ )
59
51
60
- return fuzz(syntheticArrayLengthMethodDescription, ConstantsModelProvider )
52
+ return fuzzedLengths
61
53
.map { (it.single().model as UtPrimitiveModel ).value as Int }
62
54
.filter { it in 0 .. 10 }
63
55
.toSet()
@@ -66,24 +58,24 @@ class ArrayModelProvider(
66
58
67
59
private fun generateArrayRecursively (arrayClassId : ClassId , description : FuzzedMethodDescription , length : Int ): Sequence <FuzzedValue > {
68
60
val elementClassId = arrayClassId.elementClassId ? : error(" expected ClassId for array but got ${arrayClassId.name} " )
69
- val syntheticArrayElementSetterMethodDescription = FuzzedMethodDescription (
70
- " ${arrayClassId.simpleName} OfLength$length <syntheticArrayElementSetter>" ,
71
- voidClassId,
72
- List (length) { elementClassId },
73
- description.concreteValues
74
- ).apply {
75
- packageName = description.packageName
76
- }
77
- return fuzz(syntheticArrayElementSetterMethodDescription, defaultModelProviders(idGenerator)).map {
78
- FuzzedValue (
79
- UtArrayModel (
80
- idGenerator.createId(),
81
- arrayClassId,
82
- length,
83
- elementClassId.defaultValueModel(),
84
- it.withIndex().associate { it.index to it.value.model }.toMutableMap()
85
- )
86
- )
61
+ return fuzzValuesRecursively(
62
+ types = List (length) { elementClassId },
63
+ baseMethodDescription = description,
64
+ modelProvider = generateRecursiveProvider(),
65
+ generatedValuesName = " elements of array"
66
+ ).map { elements ->
67
+ createFuzzedArrayModel(arrayClassId, length, elements.map { it.model })
87
68
}
88
69
}
70
+
71
+ private fun createFuzzedArrayModel (arrayClassId : ClassId , length : Int , values : List <UtModel >? ) =
72
+ UtArrayModel (
73
+ idGenerator.createId(),
74
+ arrayClassId,
75
+ length,
76
+ arrayClassId.elementClassId!! .defaultValueModel(),
77
+ values?.withIndex()?.associate { it.index to it.value }?.toMutableMap() ? : mutableMapOf ()
78
+ ).fuzzed {
79
+ this .summary = " %var% = ${arrayClassId.elementClassId!! .simpleName} [$length ]"
80
+ }
89
81
}
0 commit comments