11package org.utbot.instrumentation.instrumentation.execution.constructors
22
3- import java.lang.reflect.Modifier
4- import java.util.IdentityHashMap
5- import kotlin.reflect.KClass
63import org.mockito.Mockito
74import org.mockito.stubbing.Answer
85import org.objectweb.asm.Type
96import org.utbot.common.Reflection
107import org.utbot.common.invokeCatching
11- import org.utbot.framework.plugin.api.util.constructor.CapturedArgument
12- import org.utbot.framework.plugin.api.util.constructor.constructLambda
13- import org.utbot.framework.plugin.api.util.constructor.constructStaticLambda
14- import org.utbot.instrumentation.instrumentation.execution.mock.InstanceMockController
15- import org.utbot.instrumentation.instrumentation.execution.mock.InstrumentationContext
16- import org.utbot.instrumentation.instrumentation.execution.mock.MethodMockController
17- import org.utbot.instrumentation.instrumentation.execution.mock.MockController
188import org.utbot.framework.plugin.api.ClassId
199import org.utbot.framework.plugin.api.ConstructorId
2010import org.utbot.framework.plugin.api.ExecutableId
2111import org.utbot.framework.plugin.api.FieldId
22- import org.utbot.framework.plugin.api.FieldMockTarget
2312import org.utbot.framework.plugin.api.MethodId
24- import org.utbot.framework.plugin.api.MockId
25- import org.utbot.framework.plugin.api.MockInfo
26- import org.utbot.framework.plugin.api.MockTarget
27- import org.utbot.framework.plugin.api.ObjectMockTarget
28- import org.utbot.framework.plugin.api.ParameterMockTarget
2913import org.utbot.framework.plugin.api.UtArrayModel
3014import org.utbot.framework.plugin.api.UtAssembleModel
3115import org.utbot.framework.plugin.api.UtClassRefModel
@@ -35,24 +19,32 @@ import org.utbot.framework.plugin.api.UtDirectSetFieldModel
3519import org.utbot.framework.plugin.api.UtEnumConstantModel
3620import org.utbot.framework.plugin.api.UtExecutableCallModel
3721import org.utbot.framework.plugin.api.UtLambdaModel
38- import org.utbot.framework.plugin.api.UtMockValue
3922import org.utbot.framework.plugin.api.UtModel
4023import org.utbot.framework.plugin.api.UtNewInstanceInstrumentation
4124import org.utbot.framework.plugin.api.UtNullModel
4225import org.utbot.framework.plugin.api.UtPrimitiveModel
4326import org.utbot.framework.plugin.api.UtReferenceModel
4427import org.utbot.framework.plugin.api.UtStaticMethodInstrumentation
4528import org.utbot.framework.plugin.api.UtVoidModel
46- import org.utbot.framework.plugin.api.isMockModel
29+ import org.utbot.framework.plugin.api.util.anyInstance
4730import org.utbot.framework.plugin.api.util.constructor
31+ import org.utbot.framework.plugin.api.util.constructor.CapturedArgument
32+ import org.utbot.framework.plugin.api.util.constructor.constructLambda
33+ import org.utbot.framework.plugin.api.util.constructor.constructStaticLambda
4834import org.utbot.framework.plugin.api.util.executableId
4935import org.utbot.framework.plugin.api.util.isStatic
5036import org.utbot.framework.plugin.api.util.jClass
5137import org.utbot.framework.plugin.api.util.jField
5238import org.utbot.framework.plugin.api.util.method
5339import org.utbot.framework.plugin.api.util.utContext
54- import org.utbot.framework.plugin.api.util.anyInstance
40+ import org.utbot.instrumentation.instrumentation.execution.mock.InstanceMockController
41+ import org.utbot.instrumentation.instrumentation.execution.mock.InstrumentationContext
42+ import org.utbot.instrumentation.instrumentation.execution.mock.MethodMockController
43+ import org.utbot.instrumentation.instrumentation.execution.mock.MockController
5544import org.utbot.instrumentation.process.runSandbox
45+ import java.lang.reflect.Modifier
46+ import java.util.*
47+ import kotlin.reflect.KClass
5648
5749/* *
5850 * Constructs values (including mocks) from models.
@@ -82,39 +74,17 @@ class MockValueConstructor(
8274
8375 // TODO: JIRA:1379 -- replace UtReferenceModel with Int
8476 private val constructedObjects = HashMap <UtReferenceModel , Any >()
85- private val mockInfo = mutableListOf<MockInfo >()
86- private var mockTarget: MockTarget ? = null
87- private var mockCounter = 0
8877
8978 /* *
9079 * Controllers contain info about mocked methods and have to be closed to restore initial state.
9180 */
9281 private val controllers = mutableListOf<MockController >()
9382
94- /* *
95- * Sets mock context (possible mock target) before block execution and restores previous one after block execution.
96- */
97- private inline fun <T > withMockTarget (target : MockTarget ? , block : () -> T ): T {
98- val old = mockTarget
99- try {
100- mockTarget = target
101- return block()
102- } finally {
103- mockTarget = old
104- }
105- }
106-
10783 fun constructMethodParameters (models : List <UtModel >): List <UtConcreteValue <* >> =
108- models.mapIndexed { index, model ->
109- val target = mockTarget(model) { ParameterMockTarget (model.classId.name, index) }
110- construct(model, target)
111- }
84+ models.mapIndexed { _, model -> construct(model) }
11285
11386 fun constructStatics (staticsBefore : Map <FieldId , UtModel >): Map <FieldId , UtConcreteValue <* >> =
114- staticsBefore.mapValues { (field, model) -> // TODO: refactor this
115- val target = FieldMockTarget (model.classId.name, field.declaringClass.name, owner = null , field.name)
116- construct(model, target)
117- }
87+ staticsBefore.mapValues { (_, model) -> construct(model) }
11888
11989 /* *
12090 * Main construction method.
@@ -124,7 +94,7 @@ class MockValueConstructor(
12494 *
12595 * Takes mock creation context (possible mock target) to create mock if required.
12696 */
127- private fun construct (model : UtModel , target : MockTarget ? ): UtConcreteValue <* > = withMockTarget(target) {
97+ private fun construct (model : UtModel ): UtConcreteValue <* > =
12898 when (model) {
12999 is UtNullModel -> UtConcreteValue (null , model.classId.jClass)
130100 is UtPrimitiveModel -> UtConcreteValue (model.value, model.classId.jClass)
@@ -138,7 +108,6 @@ class MockValueConstructor(
138108 // PythonModel, JsUtModel may be here
139109 else -> throw UnsupportedOperationException ()
140110 }
141- }
142111
143112 /* *
144113 * Constructs an Enum<*> instance by model, uses reference-equality cache.
@@ -157,22 +126,6 @@ class MockValueConstructor(
157126 private fun constructObject (model : UtCompositeModel ): Any {
158127 constructedObjects[model]?.let { return it }
159128
160- this .mockTarget?.let { mockTarget ->
161- model.mocks.forEach { (methodId, models) ->
162- mockInfo + = MockInfo (mockTarget, methodId, models.map { model ->
163- if (model.isMockModel()) {
164- val mockId = MockId (" mock${++ mockCounter} " )
165- // Call to "construct" method still required to collect mock interaction
166- construct(model, ObjectMockTarget (model.classId.name, mockId))
167- UtMockValue (mockId, model.classId.name)
168- } else {
169- construct(model, target = null )
170- }
171- })
172- }
173- }
174-
175-
176129 val javaClass = javaClass(model.classId)
177130
178131 val classInstance = if (! model.isMock) {
@@ -181,9 +134,18 @@ class MockValueConstructor(
181134 constructedObjects[model] = notMockInstance
182135 notMockInstance
183136 } else {
184- val mockInstance = generateMockitoMock(javaClass, model.mocks)
137+ val concreteValues = model.mocks.mapValues { mutableListOf<Any ?>() }
138+ val mockInstance = generateMockitoMock(javaClass, concreteValues)
185139
186140 constructedObjects[model] = mockInstance
141+
142+ concreteValues.forEach { (executableId, valuesList) ->
143+ val mockModels = model.mocks.getValue(executableId)
144+ // If model is unit, then null should be returned (this model has to be already constructed).
145+ val constructedValues = mockModels.map { model -> construct(model).value.takeIf { it != Unit } }
146+ valuesList.addAll(constructedValues)
147+ }
148+
187149 mockInstance
188150 }
189151
@@ -194,10 +156,7 @@ class MockValueConstructor(
194156
195157 check(Reflection .isModifiersAccessible())
196158
197- val target = mockTarget(fieldModel) {
198- FieldMockTarget (fieldModel.classId.name, model.classId.name, UtConcreteValue (classInstance), fieldId.name)
199- }
200- val value = construct(fieldModel, target).value
159+ val value = construct(fieldModel).value
201160 val instance = if (Modifier .isStatic(declaredField.modifiers)) null else classInstance
202161 declaredField.set(instance, value)
203162 declaredField.isAccessible = accessible
@@ -206,16 +165,8 @@ class MockValueConstructor(
206165 return classInstance
207166 }
208167
209- private fun generateMockitoAnswer (methodToValues : Map <in ExecutableId , List <UtModel >>): Answer <* > {
210- val pointers = methodToValues.mapValues { (_, _) -> 0 }.toMutableMap()
211- val concreteValues = methodToValues.mapValues { (_, models) ->
212- models.map { model ->
213- val mockId = MockId (" mock${++ mockCounter} " )
214- val target = mockTarget(model) { ObjectMockTarget (model.classId.name, mockId) }
215- construct(model, target).value.takeIf { it != Unit } // if it is unit, then null should be returned
216- // This model has to be already constructed, so it is OK to pass null as a target
217- }
218- }
168+ private fun generateMockitoAnswer (concreteValues : Map <ExecutableId , List <Any ?>>): Answer <* > {
169+ val pointers = concreteValues.mapValues { (_, _) -> 0 }.toMutableMap()
219170 return Answer { invocation ->
220171 with (invocation.method) {
221172 pointers[executableId].let { pointer ->
@@ -232,8 +183,9 @@ class MockValueConstructor(
232183 }
233184 }
234185
235- private fun generateMockitoMock (clazz : Class <* >, mocks : Map <ExecutableId , List <UtModel >>): Any {
236- return Mockito .mock(clazz, generateMockitoAnswer(mocks))
186+ private fun generateMockitoMock (clazz : Class <* >, concreteValues : Map <ExecutableId , List <Any ?>>): Any {
187+ val answer = generateMockitoAnswer(concreteValues)
188+ return Mockito .mock(clazz, answer)
237189 }
238190
239191 private fun computeConcreteValuesForMethods (
@@ -341,7 +293,7 @@ class MockValueConstructor(
341293 constructedObjects[model] = instance
342294 for (i in instance.indices) {
343295 val elementModel = stores[i] ? : constModel
344- val value = construct(elementModel, null ).value
296+ val value = construct(elementModel).value
345297 try {
346298 java.lang.reflect.Array .set(instance, i, value)
347299 } catch (iae: IllegalArgumentException ) {
@@ -435,7 +387,6 @@ class MockValueConstructor(
435387 val instanceModel = directSetterModel.instance
436388 val instance = value(instanceModel)
437389
438- val instanceClassId = instanceModel.classId
439390 val fieldModel = directSetterModel.fieldModel
440391
441392 val field = directSetterModel.fieldId.jField
@@ -445,18 +396,8 @@ class MockValueConstructor(
445396 // set field accessible to support protected or package-private direct setters
446397 field.isAccessible = true
447398
448- // prepare mockTarget for field if it is a mock
449- val mockTarget = mockTarget(fieldModel) {
450- FieldMockTarget (
451- fieldModel.classId.name,
452- instanceClassId.name,
453- UtConcreteValue (javaClass(instanceClassId).anyInstance),
454- field.name
455- )
456- }
457-
458399 // construct and set the value
459- val fieldValue = construct(fieldModel, mockTarget ).value
400+ val fieldValue = construct(fieldModel).value
460401 field.set(instance, fieldValue)
461402 } finally {
462403 // restore accessibility property of the field
@@ -467,14 +408,10 @@ class MockValueConstructor(
467408 /* *
468409 * Constructs value from [UtModel].
469410 */
470- private fun value (model : UtModel ) = construct(model, null ).value
411+ private fun value (model : UtModel ) = construct(model).value
471412
472413 private fun mockAndGet (model : UtModel ): Any? {
473- val target = mockTarget(model) { // won't be called if model is not mockModel
474- val mockId = MockId (" mock${++ mockCounter} " )
475- ObjectMockTarget (model.classId.name, mockId)
476- }
477- return construct(model, target).value
414+ return construct(model).value
478415 }
479416
480417 private fun MethodId.call (args : List <Any ?>, instance : Any? ): Any? =
@@ -535,10 +472,4 @@ class MockValueConstructor(
535472 fun resetMockedMethods () {
536473 controllers.forEach { it.close() }
537474 }
538- }
539-
540- /* *
541- * Creates mock target using init lambda if model represents mock or null otherwise.
542- */
543- private fun mockTarget (model : UtModel , init : () -> MockTarget ): MockTarget ? =
544- if (model.isMockModel()) init () else null
475+ }
0 commit comments