@@ -12,14 +12,37 @@ import org.utbot.fuzzer.defaultModelProviders
1212import  org.utbot.fuzzer.exceptIsInstance 
1313import  org.utbot.fuzzer.fuzz 
1414
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+  */  
1521data class  ModelConstructor (
1622    val  neededTypes :  List <ClassId >,
17-     val  createModel :  (List <FuzzedValue >) ->  FuzzedValue 
23+     val  createModel :  (subModels:  List <FuzzedValue >) ->  FuzzedValue 
1824)
1925
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+  */  
2043abstract  class  RecursiveModelProvider (
21-     protected   val  idGenerator :  IdentityPreservingIdGenerator <Int >,
22-     protected   val  recursionDepthLeft :  Int 
44+     val  idGenerator :  IdentityPreservingIdGenerator <Int >,
45+     val  recursionDepthLeft :  Int 
2346): ModelProvider {
2447    var  modelProviderForRecursiveCalls:  ModelProvider  =  defaultModelProviders(idGenerator, recursionDepthLeft -  1 )
2548
@@ -33,12 +56,7 @@ abstract class RecursiveModelProvider(
3356        if  (recursionDepthLeft >  0 )
3457            modelProviderForRecursiveCalls.map {
3558                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)
4260                else 
4361                    it
4462            }
@@ -47,9 +65,24 @@ abstract class RecursiveModelProvider(
4765                .exceptIsInstance<RecursiveModelProvider >()
4866                .withFallback(fallbackProvider)
4967
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 
5172
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 , classId :  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+     }
5386
5487    final  override  fun  generate (description :  FuzzedMethodDescription ): Sequence <FuzzedParameter > =  sequence {
5588        description.parametersMap.asSequence().forEach { (classId, indices) -> 
@@ -72,7 +105,7 @@ abstract class RecursiveModelProvider(
72105        if  (types.isEmpty())
73106            return  sequenceOf(listOf ())
74107        val  syntheticMethodDescription =  FuzzedMethodDescription (
75-             " <synthetic method for RecursiveModelProvider>" //   TODO: maybe add something  here
108+             " <synthetic method for RecursiveModelProvider>" // TODO: maybe add more info  here
76109            voidClassId,
77110            types,
78111            baseMethodDescription.concreteValues
0 commit comments