33package org.utbot.greyboxfuzzer.generator.userclasses.generator
44
55import org.utbot.common.isAbstract
6- import org.utbot.greyboxfuzzer.generator.DataGenerator
76import org.utbot.greyboxfuzzer.generator.QuickCheckExtensions
87import org.utbot.greyboxfuzzer.util.*
98import org.utbot.greyboxfuzzer.util.logger
109import org.utbot.framework.plugin.api.*
1110import org.utbot.framework.plugin.api.util.executableId
1211import org.utbot.framework.plugin.api.util.id
1312import org.utbot.framework.plugin.api.util.objectClassId
13+ import org.utbot.greyboxfuzzer.generator.GreyBoxFuzzerGeneratorsAndSettings.generatorRepository
14+ import org.utbot.greyboxfuzzer.generator.getOrProduceGenerator
15+ import org.utbot.greyboxfuzzer.generator.userclasses.UserClassGenerator
1416import org.utbot.greyboxfuzzer.quickcheck.generator.GenerationStatus
1517import org.utbot.greyboxfuzzer.quickcheck.generator.GeneratorContext
1618import org.utbot.greyboxfuzzer.quickcheck.internal.ParameterTypeContext
@@ -30,6 +32,9 @@ class InterfaceImplementationsInstanceGenerator(
3032 override fun generate (): UtModel {
3133 // Try to generate with statics with some probability
3234 val clazz = resolvedType.toClass() ? : return UtNullModel (objectClassId)
35+ if (clazz.name.contains(" HttpOutputMessage" )) {
36+ println ()
37+ }
3338 if (Random .getTrue(50 )) {
3439 try {
3540 StaticsBasedInstanceGenerator (
@@ -47,10 +52,20 @@ class InterfaceImplementationsInstanceGenerator(
4752 }
4853 }
4954 val genericsContext =
50- QuickCheckExtensions .getRandomImplementerGenericContext(clazz, resolvedType)// ?: return UtNullModel(clazz.id)
51- if (genericsContext == null || Random .getTrue(30 )) {
52- return generateMock(clazz, resolvedType, typeContext, generatorContext)
55+ QuickCheckExtensions .getRandomImplementerGenericContext(
56+ clazz,
57+ resolvedType
58+ )// ?: return UtNullModel(clazz.id)
59+ logger.debug { " Implementer of ${clazz.name} ! It is a ${genericsContext?.currentClass()?.name} " }
60+ if (genericsContext == null || Random .getTrue(5 )) {
61+ logger.debug { " Generate mock anyway" }
62+ return try {
63+ generateMock(clazz, resolvedType, typeContext, generatorContext)
64+ } catch (e: Throwable ) {
65+ UtNullModel (clazz.id)
66+ }
5367 }
68+ logger.debug { " Trying to generate implementer ${genericsContext.currentClass().name} " }
5469 val resUtModel =
5570 ClassesInstanceGenerator (
5671 genericsContext.currentClass(),
@@ -79,13 +94,22 @@ class InterfaceImplementationsInstanceGenerator(
7994 )
8095 else -> resUtModel
8196 }
82- .let {
83- if (it is UtNullModel && Random .getTrue(50 )) generateMock(
84- clazz,
85- resolvedType,
86- typeContext,
87- generatorContext
88- ) else it
97+ .let {
98+ if (it is UtNullModel && Random .getTrue(50 )) {
99+ try {
100+ generateMock(
101+ clazz,
102+ resolvedType,
103+ typeContext,
104+ generatorContext
105+ )
106+ }catch (e: Throwable ) {
107+ it
108+ }
109+ }
110+ else {
111+ it
112+ }
89113 }
90114 }
91115
@@ -95,33 +119,45 @@ class InterfaceImplementationsInstanceGenerator(
95119 typeContext : GenericsContext ,
96120 generatorContext : GeneratorContext
97121 ): UtModel {
122+ logger.debug { " Mock generation" }
98123 if (! clazz.isInterface) return UtNullModel (clazz.id)
99124 val sootClazz = clazz.toSootClass() ? : return UtNullModel (clazz.id)
100125 val constructor = generatorContext.utModelConstructor
101126 val allNeededInterfaces = clazz.methods.map { it.declaringClass }.filter { it != clazz }.toSet()
102- val chainToGenericsContext = allNeededInterfaces.map { cl ->
103- val chain = cl.toSootClass()
104- ?.getImplementersOfWithChain()
105- ?.filter { it.contains(sootClazz) }
106- ?.map { it.dropLastWhile { it != sootClazz } }
107- ?.minByOrNull { it.size }
108- ?.map { it.toJavaClass() }
109- if (chain == null || chain.any { it == null }) {
110- null
111- } else {
112- cl to QuickCheckExtensions .buildGenericsContextForInterfaceParent(
113- resolvedType,
114- clazz,
115- chain.map { it!! }.reversed().drop(1 )
116- )
117- }
118- }
119- val allChainToGenericsContext = chainToGenericsContext + (clazz to typeContext)
127+ val allChainToGenericsContext = allNeededInterfaces.map { it to ParameterTypeContext .forClass(it).generics } + (clazz to typeContext)
128+ // if (allNeededInterfaces.all { it.typeParameters.isEmpty() }) {
129+ // allNeededInterfaces.map { it to ParameterTypeContext.forType(it).generics }
130+ // } else {
131+ // //TODO debug this
132+ // val chainToGenericsContext = allNeededInterfaces.map { cl ->
133+ // val chain = cl.toSootClass()
134+ // ?.getImplementersOfWithChain(onlyConcreteClasses = false, allowNotOnlyStdLib = true)
135+ // ?.filter { it.contains(sootClazz) }
136+ // ?.map { it.dropLastWhile { it != sootClazz } }
137+ // ?.minByOrNull { it.size }
138+ // ?.map { it.toJavaClass() }
139+ // if (chain == null || chain.any { it == null }) {
140+ // null
141+ // } else {
142+ // cl to QuickCheckExtensions.buildGenericsContextForInterfaceParent(
143+ // resolvedType,
144+ // clazz,
145+ // chain.map { it!! }.reversed().drop(1)
146+ // )
147+ // }
148+ // }
149+ // chainToGenericsContext + (clazz to typeContext)
150+ // }
151+ // val allChainToGenericsContext = chainToGenericsContext + (clazz to typeContext)
120152 val mocks = clazz.methods
121153 .filter { it.isAbstract }
122154 .associateTo(mutableMapOf ()) { method ->
123155 val genericsContextForMethod =
124- allChainToGenericsContext.find { it!! .first == method.declaringClass }?.second
156+ try {
157+ allChainToGenericsContext.find { it!! .first == method.declaringClass }?.second
158+ } catch (e: Throwable ) {
159+ null
160+ }
125161 val methodReturnType =
126162 if (genericsContextForMethod != null ) {
127163 genericsContextForMethod.method(method).resolveReturnType().let {
@@ -133,13 +169,7 @@ class InterfaceImplementationsInstanceGenerator(
133169 val parameterTypeContext = ParameterTypeContext .forType(methodReturnType, genericsContextForMethod)
134170 val generatedUtModelWithReturnType =
135171 try {
136- DataGenerator .generateUtModel(
137- parameterTypeContext,
138- depth,
139- generatorContext,
140- sourceOfRandomness,
141- generationStatus
142- )
172+ generateUtModelForMock(parameterTypeContext, depth, generatorContext, sourceOfRandomness, generationStatus)
143173 } catch (_: Throwable ) {
144174 UtNullModel (methodReturnType.toClass()!! .id)
145175 }
@@ -148,6 +178,34 @@ class InterfaceImplementationsInstanceGenerator(
148178 return UtCompositeModel (constructor .computeUnusedIdAndUpdate(), clazz.id, isMock = true , mocks = mocks)
149179 }
150180
181+ private fun generateUtModelForMock (
182+ parameterTypeContext : ParameterTypeContext ,
183+ depth : Int = 0,
184+ generatorContext : GeneratorContext ,
185+ random : SourceOfRandomness ,
186+ status : GenerationStatus
187+ ): UtModel {
188+ val classId = parameterTypeContext.rawClass.id
189+ logger.debug { " Trying to generate UtModel of type ${classId.name} 3 times" }
190+ if (parameterTypeContext.getAllSubParameterTypeContexts(sourceOfRandomness).any { it.rawClass.isInterface }) {
191+ return UtNullModel (classId)
192+ }
193+ var generatedInstance: UtModel ?
194+ repeat(3 ) {
195+ generatedInstance =
196+ try {
197+ val generator =
198+ generatorRepository.getOrProduceGenerator(parameterTypeContext, generatorContext, depth)
199+ ? : return @repeat
200+ generator.generateImpl(random, status)
201+ } catch (_: Throwable ) {
202+ null
203+ }
204+ generatedInstance?.let { if (it !is UtNullModel ) return it }
205+ }
206+ return UtNullModel (classId)
207+ }
208+
151209// private fun buildGenericsContextForInterfaceParent(resolvedType: Type, clazz: Class<*>, parentChain: List<Class<*>>): GenericsContext? {
152210// val generics = mutableListOf<Pair<Type, MutableList<Type>>>()
153211// var curClass = clazz
0 commit comments