@@ -12,14 +12,37 @@ import org.utbot.fuzzer.defaultModelProviders
12
12
import org.utbot.fuzzer.exceptIsInstance
13
13
import org.utbot.fuzzer.fuzz
14
14
15
+ /* *
16
+ * Auxiliary data class that stores information describing how to construct model from parts (submodels)
17
+ *
18
+ * @param neededTypes list containing type ([ClassId]) of each submodel
19
+ * @param createModel lambda that takes subModels (they should have types listed in [neededTypes]) and generates a model using them
20
+ */
15
21
data class ModelConstructor (
16
22
val neededTypes : List <ClassId >,
17
- val createModel : (List <FuzzedValue >) -> FuzzedValue
23
+ val createModel : (subModels: List <FuzzedValue >) -> FuzzedValue
18
24
)
19
25
26
+ /* *
27
+ * Abstraction for providers that may call other providers recursively inside them. [generate] will firstly get possible
28
+ * model constructors (provided by [generateModelConstructors]) and then fuzz parameters for each of them using synthetic method
29
+ *
30
+ * @param recursionDepthLeft maximum recursion level, i.e. maximum number of nested calls produced by this provider
31
+ *
32
+ * @property modelProviderForRecursiveCalls providers that can be called by this provider.
33
+ * Note that if [modelProviderForRecursiveCalls] has instances of [RecursiveModelProvider] then this provider will use
34
+ * their copies created by [createNewInstance] rather than themselves (this is important because we have to change some
35
+ * properties like [recursionDepthLeft], [totalLimit], etc.)
36
+ *
37
+ * @property fallbackProvider provider that will be used instead [modelProviderForRecursiveCalls] after reaching maximum recursion level
38
+ *
39
+ * @property totalLimit maximum number of parameters produced by this provider
40
+ *
41
+ * @property branchingLimit maximum number of [ModelConstructor]s used by [generate] (see [generateModelConstructors])
42
+ */
20
43
abstract class RecursiveModelProvider (
21
- protected val idGenerator : IdentityPreservingIdGenerator <Int >,
22
- protected val recursionDepthLeft : Int
44
+ val idGenerator : IdentityPreservingIdGenerator <Int >,
45
+ val recursionDepthLeft : Int
23
46
): ModelProvider {
24
47
var modelProviderForRecursiveCalls: ModelProvider = defaultModelProviders(idGenerator, recursionDepthLeft - 1 )
25
48
@@ -33,12 +56,7 @@ abstract class RecursiveModelProvider(
33
56
if (recursionDepthLeft > 0 )
34
57
modelProviderForRecursiveCalls.map {
35
58
if (it is RecursiveModelProvider )
36
- it.copy(idGenerator, recursionDepthLeft - 1 ).apply {
37
- modelProviderForRecursiveCalls = this @RecursiveModelProvider.modelProviderForRecursiveCalls
38
- fallbackProvider = this @RecursiveModelProvider.fallbackProvider
39
- totalLimit = this @RecursiveModelProvider.totalLimit / numOfBranches
40
- branchingLimit = this @RecursiveModelProvider.branchingLimit
41
- }
59
+ it.createNewInstance(this , totalLimit / numOfBranches)
42
60
else
43
61
it
44
62
}
@@ -47,9 +65,24 @@ abstract class RecursiveModelProvider(
47
65
.exceptIsInstance<RecursiveModelProvider >()
48
66
.withFallback(fallbackProvider)
49
67
50
- abstract fun copy (idGenerator : IdentityPreservingIdGenerator <Int >, recursionDepthLeft : Int ): RecursiveModelProvider
68
+ /* *
69
+ * Creates instance of the class on which it is called, assuming that it will be called recursively from [parentProvider]
70
+ */
71
+ protected abstract fun createNewInstance (parentProvider : RecursiveModelProvider , newTotalLimit : Int ): RecursiveModelProvider
51
72
52
- abstract fun generateModelConstructors (description : FuzzedMethodDescription , clazz : ClassId ): List <ModelConstructor >
73
+ /* *
74
+ * Creates [ModelProvider]s that will be used to generate values recursively. The order of elements in returned list is important:
75
+ * only first [branchingLimit] constructors will be used, so you should place most effective providers first
76
+ */
77
+ protected abstract fun generateModelConstructors (description : FuzzedMethodDescription , clazz : ClassId ): List <ModelConstructor >
78
+
79
+ protected fun copySettingsFrom (otherProvider : RecursiveModelProvider ): RecursiveModelProvider {
80
+ modelProviderForRecursiveCalls = otherProvider.modelProviderForRecursiveCalls
81
+ fallbackProvider = otherProvider.fallbackProvider
82
+ totalLimit = otherProvider.totalLimit
83
+ branchingLimit = otherProvider.branchingLimit
84
+ return this
85
+ }
53
86
54
87
final override fun generate (description : FuzzedMethodDescription ): Sequence <FuzzedParameter > = sequence {
55
88
description.parametersMap.asSequence().forEach { (classId, indices) ->
@@ -72,7 +105,7 @@ abstract class RecursiveModelProvider(
72
105
if (types.isEmpty())
73
106
return sequenceOf(listOf ())
74
107
val syntheticMethodDescription = FuzzedMethodDescription (
75
- " <synthetic method for RecursiveModelProvider>" , // TODO: maybe add something here
108
+ " <synthetic method for RecursiveModelProvider>" , // TODO: maybe add more info here
76
109
voidClassId,
77
110
types,
78
111
baseMethodDescription.concreteValues
0 commit comments