@@ -10,56 +10,70 @@ import org.utbot.external.api.classIdForType
10
10
import org.utbot.framework.plugin.api.ClassId
11
11
import org.utbot.framework.plugin.api.UtModel
12
12
import org.utbot.framework.plugin.api.UtNullModel
13
+ import org.utbot.framework.plugin.api.util.id
13
14
import org.utbot.framework.plugin.api.util.jClass
15
+ import org.utbot.framework.plugin.api.util.objectClassId
16
+ import org.utbot.quickcheck.generator.GenerationState
17
+ import org.utbot.quickcheck.generator.GeneratorContext
14
18
import java.lang.reflect.Parameter
15
19
16
20
object DataGenerator {
17
21
18
22
private val generatorRepository = GreyBoxFuzzerGenerators .generatorRepository
19
23
20
- fun generate (
21
- clazz : Class <* >,
22
- random : SourceOfRandomness ,
23
- status : GenerationStatus
24
- ): UtModel ? = generatorRepository.getOrProduceGenerator(clazz)?.generateImpl(random, status)
25
-
26
- fun generate (
24
+ fun generateUtModel (
27
25
parameterTypeContext : ParameterTypeContext ,
26
+ depth : Int = 0,
27
+ generatorContext : GeneratorContext ,
28
28
random : SourceOfRandomness ,
29
29
status : GenerationStatus
30
- ): UtModel ? = generatorRepository.getOrProduceGenerator(parameterTypeContext, 0 )?.generateImpl(random, status)
31
-
32
- fun generate (
33
- parameterTypeContext : ParameterTypeContext ,
34
- random : SourceOfRandomness ,
35
- status : GenerationStatus ,
36
- depth : Int
37
- ): UtModel ? = generatorRepository.getOrProduceGenerator(parameterTypeContext, depth)?.generateImpl(random, status)
30
+ ): UtModel {
31
+ logger.debug { " Trying to generate UtModel of type 3 times" }
32
+ val classId = parameterTypeContext.rawClass.id
33
+ var generatedInstance: UtModel ? = null
34
+ repeat(3 ) {
35
+ generatedInstance =
36
+ try {
37
+ val generator =
38
+ generatorRepository.getOrProduceGenerator(parameterTypeContext, generatorContext, depth)
39
+ ? : return @repeat
40
+ generator.generatorContext.startCheckpoint()
41
+ generator.generateImpl(random, status)
42
+ } catch (_: Throwable ) {
43
+ null
44
+ }
45
+ generatedInstance?.let { if (it !is UtNullModel ) return it }
46
+ }
47
+ return UtNullModel (classId)
48
+ }
38
49
39
50
fun generate (
40
51
parameter : Parameter ,
41
52
parameterIndex : Int ,
53
+ generatorContext : GeneratorContext ,
42
54
random : SourceOfRandomness ,
43
55
status : GenerationStatus
44
56
): FParameter {
45
57
val generator =
46
- generatorRepository.getOrProduceGenerator(parameter, parameterIndex)
58
+ generatorRepository.getOrProduceGenerator(parameter, parameterIndex, generatorContext )
47
59
return generate(generator, parameter, random, status)
48
60
}
49
61
50
62
fun generateThis (
51
63
classId : ClassId ,
64
+ generatorContext : GeneratorContext ,
52
65
random : SourceOfRandomness ,
53
66
status : GenerationStatus
54
67
): NormalMethodThisInstance {
55
68
val generator =
56
- generatorRepository.getOrProduceGenerator(classId.jClass)
57
- return generateThis(generator, classId, random, status)
69
+ generatorRepository.getOrProduceGenerator(classId.jClass, generatorContext )
70
+ return generateThis(generator, classId, generatorContext, random, status)
58
71
}
59
72
60
73
private fun generateThis (
61
74
generator : Generator ? ,
62
75
classId : ClassId ,
76
+ generatorContext : GeneratorContext ,
63
77
random : SourceOfRandomness ,
64
78
status : GenerationStatus ,
65
79
numberOfTries : Int = 3
@@ -70,10 +84,13 @@ object DataGenerator {
70
84
throw FuzzerIllegalStateException (" Can't find generator for ${classId.name} " )
71
85
}
72
86
var generatedValue: UtModel
73
- repeat(numberOfTries) {
74
- logger.debug { " Try $it " }
87
+ repeat(numberOfTries) { iteration ->
88
+ logger.debug { " Try $iteration " }
75
89
try {
90
+ generator.generationState = GenerationState .REGENERATE
91
+ generator.generatorContext.startCheckpoint()
76
92
generatedValue = generator.generateImpl(random, status)
93
+ if (generatedValue is UtNullModel && iteration != numberOfTries - 1 ) return @repeat
77
94
return NormalMethodThisInstance (
78
95
generatedValue,
79
96
generator,
@@ -104,7 +121,10 @@ object DataGenerator {
104
121
repeat(numberOfTries) {
105
122
logger.debug { " Try $it " }
106
123
try {
124
+ generator.generationState = GenerationState .REGENERATE
125
+ generator.generatorContext.startCheckpoint()
107
126
generatedValue = generator.generateImpl(random, status)
127
+ if (generatedValue is UtNullModel ) return @repeat
108
128
return FParameter (
109
129
parameter,
110
130
null ,
@@ -120,158 +140,4 @@ object DataGenerator {
120
140
return FParameter (parameter, null , UtNullModel (classId), generator, classId, listOf ())
121
141
}
122
142
123
- // //TODO Make it work with type parameters
124
- // private fun Type.getFFieldsForClass(value: Any, depth: Int, originalField: Field?): List<FField> {
125
- // println("GETTING FFIelds from $value")
126
- // createFFieldFromPrimitivesOrBoxedPrimitives(this, value, originalField)?.let { return listOf(it) }
127
- // val parameterizedType = this as? ParameterizedType
128
- // val genericsContext =
129
- // if (this is GenericArrayTypeImpl) {
130
- // (this.genericComponentType as? ParameterizedType)?.buildGenericsContext()
131
- // } else {
132
- // parameterizedType?.buildGenericsContext()
133
- // }
134
- // if (depth >= GreyBoxFuzzerGenerators.maxDepthOfGeneration) {
135
- // return emptyList()
136
- // }
137
- // val subFields = mutableListOf<FField>()
138
- // if (this.toClass()?.isArray == true) {
139
- // val arrayContentType = this.toClass()?.componentType ?: return subFields
140
- // getFFieldsFromArray(value, subFields, originalField, this, arrayContentType, depth)
141
- // return subFields
142
- // }
143
- // val classFields =
144
- // this.toClass()?.getAllDeclaredFields()?.filter { !it.hasModifiers(Modifier.FINAL) } ?: emptyList()
145
- // for (field in classFields) {
146
- // val resolvedFieldType =
147
- // if (genericsContext != null) {
148
- // //TODO make it work for subclasses
149
- // parameterizedType.let { field.resolveFieldType(genericsContext) } ?: field.type
150
- // } else {
151
- // field.type
152
- // }
153
- // assert(resolvedFieldType.toClass() != null)
154
- // // if (field.hasModifiers(Modifier.FINAL)) {
155
- // // //subFields.add(FField(field, value))
156
- // // continue
157
- // // }
158
- // if (resolvedFieldType.toClass()!!.isArray) {
159
- // val arrayOfObjects = field.getFieldValue(value)
160
- // val arrayContentType =
161
- // (resolvedFieldType as? GenericArrayTypeImpl)?.genericComponentType ?: field.type.componentType
162
- // getFFieldsFromArray(arrayOfObjects, subFields, field, resolvedFieldType, arrayContentType, depth)
163
- // //TODO!!!!
164
- // } else {
165
- // field.getFieldValue(value)?.let { fieldValue ->
166
- // try {
167
- // val generatorForField = generatorRepository.getOrProduceGenerator(field)
168
- // if (field.type.isPrimitive) {
169
- // subFields.add(FField(field, fieldValue, resolvedFieldType, generatorForField))
170
- // } else {
171
- // //println("GETTING SUBFIELDS FOR ${field.type} value = ${fieldValue} DEPTH = $depth")
172
- // //TODO resolve type
173
- // val subFFields = resolvedFieldType.getFFieldsForClass(fieldValue, depth + 1, null)
174
- // subFields.add(FField(field, fieldValue, resolvedFieldType, generatorForField, subFFields))
175
- // }
176
- // } catch (e: java.lang.IllegalStateException) {
177
- // subFields.add(FField(field, fieldValue, resolvedFieldType, null, listOf()))
178
- // }
179
- // } ?: subFields.add(FField(field, null, resolvedFieldType, null, listOf()))
180
- // }
181
- // }
182
- // return subFields
183
- // }
184
-
185
- // private fun createFFieldFromPrimitivesOrBoxedPrimitives(originalType: Type, value: Any?, field: Field?): FField? {
186
- // val clazz = originalType.toClass() ?: return null
187
- // val listOfPrimitives = listOf(
188
- // Byte::class,
189
- // Short::class,
190
- // Int::class,
191
- // Long::class,
192
- // Float::class,
193
- // Double::class,
194
- // Boolean::class,
195
- // Char::class,
196
- // String::class
197
- // )
198
- // return if (clazz.kotlin in listOfPrimitives || clazz.isPrimitive) {
199
- // FField(field, value, originalType, getGenerator(originalType))
200
- // } else null
201
- // }
202
-
203
- // private fun getFFieldsFromArray(
204
- // array: Any?,
205
- // subFields: MutableList<FField>,
206
- // field: Field?,
207
- // arrayType: Type,
208
- // arrayContentType: Type,
209
- // depth: Int
210
- // ) {
211
- // val typedArray =
212
- // when (array) {
213
- // is BooleanArray -> {
214
- // array.toList()
215
- // }
216
- // is ByteArray -> {
217
- // array.toList()
218
- // }
219
- // is CharArray -> {
220
- // array.toList()
221
- // }
222
- // is ShortArray -> {
223
- // array.toList()
224
- // }
225
- // is IntArray -> {
226
- // array.toList()
227
- // }
228
- // is LongArray -> {
229
- // array.toList()
230
- // }
231
- // is FloatArray -> {
232
- // array.toList()
233
- // }
234
- // is DoubleArray -> {
235
- // array.toList()
236
- // }
237
- // else -> {
238
- // if (array == null) {
239
- // subFields.add(FField(null, null, arrayContentType, null, listOf()))
240
- // return
241
- // } else {
242
- // (array as Array<*>).toList()
243
- // }
244
- // }
245
- // }
246
- // val generatorOfNeededType = field?.let { getGenerator(it, arrayType) } ?: getGenerator(arrayType)
247
- // val localSubFields = mutableListOf<FField>()
248
- // val indexOfLastNotNullElement = typedArray.indexOfLast { it != null }
249
- // val arrayContentGenerator = getGenerator(arrayContentType)
250
- // if (indexOfLastNotNullElement == -1) {
251
- // localSubFields.add(FField(field, null, arrayContentType, arrayContentGenerator))
252
- // } else {
253
- // typedArray.filterNotNull().map { el ->
254
- // val ssFFields = arrayContentType.getFFieldsForClass(el, depth + 1, null)
255
- // localSubFields.add(FField(field, el, arrayContentType, arrayContentGenerator, ssFFields))
256
- // }
257
- // }
258
- // subFields.add(FField(field, typedArray, arrayType, generatorOfNeededType, localSubFields))
259
- // }
260
-
261
- // private fun getGenerator(field: Field, fieldType: Type): Generator<*>? {
262
- // return if (fieldType is ParameterizedType) {
263
- // generatorRepository.getOrProduceGenerator(field.buildParameterContext(fieldType), 0)
264
- // } else {
265
- // generatorRepository.getOrProduceGenerator(field)
266
- // }.let { gen ->
267
- // if (gen is ComponentizedGenerator && gen.getComponents().any { it is ZilchGenerator }) null
268
- // else gen
269
- // }
270
- // }
271
- // private fun getGenerator(resolvedType: Type): Generator<*>? =
272
- // generatorRepository.getOrProduceGenerator(resolvedType).let { gen ->
273
- // if (gen is ComponentizedGenerator && gen.getComponents().any { it is ZilchGenerator }) null
274
- // else gen
275
- // }
276
-
277
143
}
0 commit comments