From 6d659472d9d258186d336b0a219280391913ba08 Mon Sep 17 00:00:00 2001 From: Sergey Pospelov Date: Mon, 19 Sep 2022 10:50:57 +0300 Subject: [PATCH 1/9] Fix: `ValueConstructor` and `MockValueConstructor` --- .../src/main/kotlin/org/utbot/engine/ValueConstructor.kt | 9 +++------ .../utbot/framework/assemble/AssembleModelGenerator.kt | 1 - .../org/utbot/framework/concrete/MockValueConstructor.kt | 8 +++----- .../utbot/fuzzer/providers/DateConstantModelProvider.kt | 1 - 4 files changed, 6 insertions(+), 13 deletions(-) diff --git a/utbot-framework/src/main/kotlin/org/utbot/engine/ValueConstructor.kt b/utbot-framework/src/main/kotlin/org/utbot/engine/ValueConstructor.kt index bcef64e327..b5b468bec0 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/engine/ValueConstructor.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/engine/ValueConstructor.kt @@ -62,14 +62,12 @@ class ValueConstructor { // TODO: JIRA:1379 -- replace UtReferenceModel with Int private val constructedObjects = HashMap() - private val resultsCache = HashMap() private val mockInfo = mutableListOf() private var mockTarget: MockTarget? = null private var mockCounter = 0 private fun clearState() { constructedObjects.clear() - resultsCache.clear() mockInfo.clear() mockTarget = null mockCounter = 0 @@ -337,7 +335,7 @@ class ValueConstructor { } } - return resultsCache[assembleModel] + return constructedObjects[assembleModel] ?: error("Can't assemble model: $assembleModel") } @@ -375,7 +373,7 @@ class ValueConstructor { assembleModel: UtAssembleModel, ) { val executable = callModel.executable - val instanceValue = resultsCache[callModel.instance] + val instanceValue = callModel.instance?.let { value(it) } val params = callModel.params.map { value(it) } val result = when (executable) { @@ -386,7 +384,6 @@ class ValueConstructor { // Ignore result if returnId is null. Otherwise add it to instance cache. callModel.returnValue?.let { checkNotNull(result) { "Tracked instance can't be null for call $executable in model $assembleModel" } - resultsCache[it] = result //If statement is final instantiating, add result to constructed objects cache if (callModel == assembleModel.finalInstantiationModel) { @@ -400,7 +397,7 @@ class ValueConstructor { */ private fun updateWithDirectSetFieldModel(directSetterModel: UtDirectSetFieldModel) { val instanceModel = directSetterModel.instance - val instance = resultsCache[instanceModel] ?: error("Model $instanceModel is not instantiated") + val instance = constructedObjects[instanceModel] ?: error("Model $instanceModel is not instantiated") val instanceClassId = instanceModel.classId val fieldModel = directSetterModel.fieldModel diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/assemble/AssembleModelGenerator.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/assemble/AssembleModelGenerator.kt index 3ea84673ec..eb1d574c74 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/assemble/AssembleModelGenerator.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/assemble/AssembleModelGenerator.kt @@ -2,7 +2,6 @@ package org.utbot.framework.assemble import org.utbot.common.isPrivate import org.utbot.common.isPublic -import org.utbot.common.packageName import org.utbot.engine.ResolvedExecution import org.utbot.engine.ResolvedModels import org.utbot.framework.UtSettings diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/MockValueConstructor.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/MockValueConstructor.kt index 4768cbf68b..2c2126de65 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/MockValueConstructor.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/MockValueConstructor.kt @@ -79,7 +79,6 @@ class MockValueConstructor( // TODO: JIRA:1379 -- replace UtReferenceModel with Int private val constructedObjects = HashMap() - private val resultsCache = HashMap() private val mockInfo = mutableListOf() private var mockTarget: MockTarget? = null private var mockCounter = 0 @@ -366,7 +365,7 @@ class MockValueConstructor( } } - return resultsCache[assembleModel] ?: error("Can't assemble model: $assembleModel") + return constructedObjects[assembleModel] ?: error("Can't assemble model: $assembleModel") } private fun constructFromLambdaModel(lambdaModel: UtLambdaModel): Any { @@ -406,7 +405,7 @@ class MockValueConstructor( assembleModel: UtAssembleModel, ) { val executable = callModel.executable - val instanceValue = resultsCache[callModel.instance] + val instanceValue = callModel.instance?.let { value(it) } val params = callModel.params.map { value(it) } val result = when (executable) { @@ -417,7 +416,6 @@ class MockValueConstructor( // Ignore result if returnId is null. Otherwise add it to instance cache. callModel.returnValue?.let { checkNotNull(result) { "Tracked instance can't be null for call $executable in model $assembleModel" } - resultsCache[it] = result //If statement is final instantiating, add result to constructed objects cache if (callModel == assembleModel.finalInstantiationModel) { @@ -431,7 +429,7 @@ class MockValueConstructor( */ private fun updateWithDirectSetFieldModel(directSetterModel: UtDirectSetFieldModel) { val instanceModel = directSetterModel.instance - val instance = resultsCache[instanceModel] ?: error("Model $instanceModel is not instantiated") + val instance = value(instanceModel) val instanceClassId = instanceModel.classId val fieldModel = directSetterModel.fieldModel diff --git a/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/providers/DateConstantModelProvider.kt b/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/providers/DateConstantModelProvider.kt index 6fab59750b..c712bf4540 100644 --- a/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/providers/DateConstantModelProvider.kt +++ b/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/providers/DateConstantModelProvider.kt @@ -142,7 +142,6 @@ class DateConstantModelProvider( "$dateFormatParse#" + id.hex(), instantiationChain ).apply { - instantiationChain += simpleDateFormatModel.allStatementsChain instantiationChain += UtExecutableCallModel( simpleDateFormatModel, dateFormatParse, listOf(UtPrimitiveModel(dateString)), returnValue = this ) From 9834d95223c2f11e889f87a4460e0d67351b6392 Mon Sep 17 00:00:00 2001 From: Sergey Pospelov Date: Mon, 19 Sep 2022 16:23:48 +0300 Subject: [PATCH 2/9] Refactor: `UtExecutableCallModel` --- .../org/utbot/framework/plugin/api/Api.kt | 5 +- .../org/utbot/engine/CollectionWrappers.kt | 3 +- .../kotlin/org/utbot/engine/ObjectWrappers.kt | 5 +- .../org/utbot/engine/OptionalWrapper.kt | 8 +- .../main/kotlin/org/utbot/engine/Resolver.kt | 2 +- .../kotlin/org/utbot/engine/StreamWrappers.kt | 3 +- .../main/kotlin/org/utbot/engine/Strings.kt | 6 +- .../org/utbot/engine/ValueConstructor.kt | 31 ++++---- .../assemble/AssembleModelGenerator.kt | 5 +- .../assemble/AssemblePrimitiveWrapper.kt | 1 - .../constructor/tree/CgVariableConstructor.kt | 74 +++++++++++-------- .../concrete/IterableConstructors.kt | 7 +- .../concrete/MockValueConstructor.kt | 28 +++---- .../concrete/OptionalConstructors.kt | 8 +- .../concrete/PrimitiveWrapperConstructor.kt | 3 +- .../concrete/UtAssembleModelConstructors.kt | 1 - .../org/utbot/fuzzer/FallbackModelProvider.kt | 2 +- .../org/utbot/fuzzer/RandomExtensions.kt | 4 - .../fuzzer/objects/AssembleModelUtils.kt | 2 +- .../providers/CollectionModelProvider.kt | 2 +- .../providers/DateConstantModelProvider.kt | 4 +- .../framework/plugin/api/ModelProviderTest.kt | 40 +++++----- 22 files changed, 116 insertions(+), 128 deletions(-) diff --git a/utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/Api.kt b/utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/Api.kt index ad2239497c..a2de8d5403 100644 --- a/utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/Api.kt +++ b/utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/Api.kt @@ -568,7 +568,6 @@ data class UtExecutableCallModel( override val instance: UtReferenceModel?, val executable: ExecutableId, val params: List, - val returnValue: UtReferenceModel? = null, ) : UtStatementModel(instance) { override fun toString() = withToStringThreadLocalReentrancyGuard { buildString { @@ -578,9 +577,7 @@ data class UtExecutableCallModel( is MethodId -> executable.name } - if (returnValue != null) { - append("val ${returnValue.modelName} = ") - } else if (instance != null) { + if (instance != null) { append("${instance.modelName}.") } diff --git a/utbot-framework/src/main/kotlin/org/utbot/engine/CollectionWrappers.kt b/utbot-framework/src/main/kotlin/org/utbot/engine/CollectionWrappers.kt index fa0b5b89e8..70689f922e 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/engine/CollectionWrappers.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/engine/CollectionWrappers.kt @@ -127,8 +127,7 @@ abstract class BaseContainerWrapper(containerClassName: String) : BaseOverridden instantiationChain += UtExecutableCallModel( instance = null, executable = constructorId(classId), - params = emptyList(), - returnValue = this + params = emptyList() ) modificationsChain += parameterModels.map { diff --git a/utbot-framework/src/main/kotlin/org/utbot/engine/ObjectWrappers.kt b/utbot-framework/src/main/kotlin/org/utbot/engine/ObjectWrappers.kt index 3fdeb2bfb9..9a6bdb742e 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/engine/ObjectWrappers.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/engine/ObjectWrappers.kt @@ -245,12 +245,11 @@ data class ThrowableWrapper(val throwable: Throwable) : WrapperInterface { return UtAssembleModel(addr, classId, modelName, instantiationChain) .apply { instantiationChain += when (val message = throwable.message) { - null -> UtExecutableCallModel(null, constructorId(classId), emptyList(), this) + null -> UtExecutableCallModel(null, constructorId(classId), emptyList()) else -> UtExecutableCallModel( null, constructorId(classId, stringClassId), - listOf(UtPrimitiveModel(message)), - this, + listOf(UtPrimitiveModel(message)) ) } } diff --git a/utbot-framework/src/main/kotlin/org/utbot/engine/OptionalWrapper.kt b/utbot-framework/src/main/kotlin/org/utbot/engine/OptionalWrapper.kt index f3b889dbd8..627c1faf5c 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/engine/OptionalWrapper.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/engine/OptionalWrapper.kt @@ -94,11 +94,11 @@ class OptionalWrapper(private val utOptionalClass: UtOptionalClass) : BaseOverri val modificationsChain = mutableListOf() return UtAssembleModel(addr, classId, modelName, instantiationChain, modificationsChain) .apply { - instantiationChain += instantiationFactoryCallModel(classId, wrapper, this) + instantiationChain += instantiationFactoryCallModel(classId, wrapper) } } - private fun Resolver.instantiationFactoryCallModel(classId: ClassId, wrapper: ObjectValue, model: UtAssembleModel) : UtExecutableCallModel { + private fun Resolver.instantiationFactoryCallModel(classId: ClassId, wrapper: ObjectValue) : UtExecutableCallModel { val valueField = FieldId(overriddenClass.id, "value") val isPresentFieldId = FieldId(overriddenClass.id, "isPresent") val values = collectFieldModels(wrapper.addr, overriddenClass.type) @@ -115,7 +115,7 @@ class OptionalWrapper(private val utOptionalClass: UtOptionalClass) : BaseOverri "empty", classId, emptyList() - ), emptyList(), model + ), emptyList() ) } else { UtExecutableCallModel( @@ -124,7 +124,7 @@ class OptionalWrapper(private val utOptionalClass: UtOptionalClass) : BaseOverri "of", classId, listOf(utOptionalClass.elementClassId) - ), listOf(valueModel), model + ), listOf(valueModel) ) } } diff --git a/utbot-framework/src/main/kotlin/org/utbot/engine/Resolver.kt b/utbot-framework/src/main/kotlin/org/utbot/engine/Resolver.kt index f42f50d63f..8164ef0222 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/engine/Resolver.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/engine/Resolver.kt @@ -553,7 +553,7 @@ class Resolver( val instantiationChain = mutableListOf() UtAssembleModel(addr, classId, nextModelName(baseModelName), instantiationChain) .apply { - instantiationChain += UtExecutableCallModel(null, constructorId, listOf(valueModel), this) + instantiationChain += UtExecutableCallModel(null, constructorId, listOf(valueModel)) } } } diff --git a/utbot-framework/src/main/kotlin/org/utbot/engine/StreamWrappers.kt b/utbot-framework/src/main/kotlin/org/utbot/engine/StreamWrappers.kt index e3cfe68a1b..d66d92720a 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/engine/StreamWrappers.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/engine/StreamWrappers.kt @@ -75,8 +75,7 @@ abstract class StreamWrapper( instantiationChain += UtExecutableCallModel( instance = null, executable = builder, - params = params, - returnValue = this + params = params ) } } diff --git a/utbot-framework/src/main/kotlin/org/utbot/engine/Strings.kt b/utbot-framework/src/main/kotlin/org/utbot/engine/Strings.kt index 8c31fda3ad..355cff5d46 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/engine/Strings.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/engine/Strings.kt @@ -186,8 +186,7 @@ class StringWrapper : BaseOverriddenWrapper(utStringClass.name) { instantiationChain += UtExecutableCallModel( instance = null, constructorId(classId, STRING_TYPE.classId), - listOf(stringModel), - this + listOf(stringModel) ) } } @@ -342,8 +341,7 @@ sealed class UtAbstractStringBuilderWrapper(className: String) : BaseOverriddenW instantiationChain += UtExecutableCallModel( instance = null, constructorId, - listOf(stringModel), - this + listOf(stringModel) ) } } diff --git a/utbot-framework/src/main/kotlin/org/utbot/engine/ValueConstructor.kt b/utbot-framework/src/main/kotlin/org/utbot/engine/ValueConstructor.kt index b5b468bec0..a620ca9a87 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/engine/ValueConstructor.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/engine/ValueConstructor.kt @@ -328,15 +328,21 @@ class ValueConstructor { private fun constructFromAssembleModel(assembleModel: UtAssembleModel): Any { constructedObjects[assembleModel]?.let { return it } - assembleModel.allStatementsChain.forEach { statementModel -> + val instantiationExecutableCall = assembleModel.instantiationChain.single() as UtExecutableCallModel + val result = updateWithExecutableCallModel(instantiationExecutableCall) + checkNotNull(result) { + "Tracked instance can't be null for call ${instantiationExecutableCall.executable} in model $assembleModel" + } + constructedObjects[assembleModel] = result + + assembleModel.modificationsChain.forEach { statementModel -> when (statementModel) { - is UtExecutableCallModel -> updateWithExecutableCallModel(statementModel, assembleModel) + is UtExecutableCallModel -> updateWithExecutableCallModel(statementModel) is UtDirectSetFieldModel -> updateWithDirectSetFieldModel(statementModel) } } - return constructedObjects[assembleModel] - ?: error("Can't assemble model: $assembleModel") + return constructedObjects[assembleModel] ?: error("Can't assemble model: $assembleModel") } private fun constructFromLambdaModel(lambdaModel: UtLambdaModel): Any { @@ -366,12 +372,13 @@ class ValueConstructor { } /** - * Updates instance state with [UtExecutableCallModel] invocation. + * Updates instance state with [callModel] invocation. + * + * @return the result of [callModel] invocation */ private fun updateWithExecutableCallModel( callModel: UtExecutableCallModel, - assembleModel: UtAssembleModel, - ) { + ): Any? { val executable = callModel.executable val instanceValue = callModel.instance?.let { value(it) } val params = callModel.params.map { value(it) } @@ -381,15 +388,7 @@ class ValueConstructor { is ConstructorId -> executable.call(params) } - // Ignore result if returnId is null. Otherwise add it to instance cache. - callModel.returnValue?.let { - checkNotNull(result) { "Tracked instance can't be null for call $executable in model $assembleModel" } - - //If statement is final instantiating, add result to constructed objects cache - if (callModel == assembleModel.finalInstantiationModel) { - constructedObjects[assembleModel] = result - } - } + return result } /** diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/assemble/AssembleModelGenerator.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/assemble/AssembleModelGenerator.kt index eb1d574c74..3ef1f52732 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/assemble/AssembleModelGenerator.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/assemble/AssembleModelGenerator.kt @@ -251,7 +251,7 @@ class AssembleModelGenerator(private val methodPackageName: String) { val constructorInfo = constructorAnalyzer.analyze(constructorId) instantiatedModels[compositeModel] = this - instantiationChain += constructorCall(compositeModel, this, constructorInfo) + instantiationChain += constructorCall(compositeModel, constructorInfo) compositeModel.fields.forEach { (fieldId, fieldModel) -> if (fieldId.isStatic) { @@ -342,7 +342,6 @@ class AssembleModelGenerator(private val methodPackageName: String) { */ private fun constructorCall( compositeModel: UtCompositeModel, - instance: UtAssembleModel, constructorInfo: ConstructorAssembleInfo, ): UtExecutableCallModel { val constructorParams = constructorInfo.constructorId.parameters.withIndex() @@ -355,7 +354,7 @@ class AssembleModelGenerator(private val methodPackageName: String) { assembleModel(fieldModel) } - return UtExecutableCallModel(null, constructorInfo.constructorId, constructorParams, instance) + return UtExecutableCallModel(null, constructorInfo.constructorId, constructorParams) } /** diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/assemble/AssemblePrimitiveWrapper.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/assemble/AssemblePrimitiveWrapper.kt index 2b83b35897..fcbd79fff3 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/assemble/AssemblePrimitiveWrapper.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/assemble/AssemblePrimitiveWrapper.kt @@ -37,7 +37,6 @@ fun assemble(model: UtPrimitiveModel): UtAssembleModel { instance = null, executable = constructorCall.executableId, params = listOf(model), - returnValue = null, ) return UtAssembleModel( diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/tree/CgVariableConstructor.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/tree/CgVariableConstructor.kt index 85d7c9893b..c0a8b2a029 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/tree/CgVariableConstructor.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/tree/CgVariableConstructor.kt @@ -16,6 +16,7 @@ import org.utbot.framework.codegen.model.constructor.util.typeCast import org.utbot.framework.codegen.model.tree.CgAllocateArray import org.utbot.framework.codegen.model.tree.CgDeclaration import org.utbot.framework.codegen.model.tree.CgEnumConstantAccess +import org.utbot.framework.codegen.model.tree.CgExecutableCall import org.utbot.framework.codegen.model.tree.CgExpression import org.utbot.framework.codegen.model.tree.CgFieldAccess import org.utbot.framework.codegen.model.tree.CgGetJavaClass @@ -200,7 +201,10 @@ internal class CgVariableConstructor(val context: CgContext) : } private fun constructAssemble(model: UtAssembleModel, baseName: String?): CgValue { - for (statementModel in model.allStatementsChain) { + val instantiationExecutableCall = model.instantiationChain.single() as UtExecutableCallModel + processInstantiationStatement(model, instantiationExecutableCall, baseName) + + for (statementModel in model.modificationsChain) { when (statementModel) { is UtDirectSetFieldModel -> { val instance = declareOrGet(statementModel.instance) @@ -208,35 +212,7 @@ internal class CgVariableConstructor(val context: CgContext) : instance[statementModel.fieldId] `=` declareOrGet(statementModel.fieldModel) } is UtExecutableCallModel -> { - val executable = statementModel.executable - val params = statementModel.params - val cgCall = when (executable) { - is MethodId -> { - val caller = statementModel.instance?.let { declareOrGet(it) } - val args = params.map { declareOrGet(it) } - caller[executable](*args.toTypedArray()) - } - is ConstructorId -> { - val args = params.map { declareOrGet(it) } - executable(*args.toTypedArray()) - } - } - - // if call result is stored in a variable - if (statementModel.returnValue == null) { - +cgCall - } else { - val type = when (executable) { - is MethodId -> executable.returnType - is ConstructorId -> executable.classId - } - - // Don't use redundant constructors for primitives and String - val initExpr = if (isPrimitiveWrapperOrString(type)) cgLiteralForWrapper(params) else cgCall - newVar(type, statementModel.returnValue, baseName) { initExpr } - .takeIf { statementModel == model.finalInstantiationModel } - ?.also { valueByModelId[model.id] = it } - } + +createCgExecutableCallFromUtExecutableCall(statementModel) } } } @@ -244,6 +220,44 @@ internal class CgVariableConstructor(val context: CgContext) : return valueByModelId.getValue(model.id) } + private fun processInstantiationStatement( + model: UtAssembleModel, + executableCall: UtExecutableCallModel, + baseName: String? + ) { + val executable = executableCall.executable + val params = executableCall.params + val cgCall = createCgExecutableCallFromUtExecutableCall(executableCall) + + val type = when (executable) { + is MethodId -> executable.returnType + is ConstructorId -> executable.classId + } + // Don't use redundant constructors for primitives and String + val initExpr = if (isPrimitiveWrapperOrString(type)) cgLiteralForWrapper(params) else cgCall + newVar(type, model, baseName) { initExpr } + .takeIf { executableCall == model.finalInstantiationModel } + ?.also { valueByModelId[model.id] = it } + } + + + private fun createCgExecutableCallFromUtExecutableCall(statementModel: UtExecutableCallModel): CgExecutableCall { + val executable = statementModel.executable + val params = statementModel.params + val cgCall = when (executable) { + is MethodId -> { + val caller = statementModel.instance?.let { declareOrGet(it) } + val args = params.map { declareOrGet(it) } + caller[executable](*args.toTypedArray()) + } + is ConstructorId -> { + val args = params.map { declareOrGet(it) } + executable(*args.toTypedArray()) + } + } + return cgCall + } + /** * Makes a replacement of constructor call to instantiate a primitive wrapper * with direct setting of the value. The reason is that in Kotlin constructors diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/IterableConstructors.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/IterableConstructors.kt index 68955136e0..b9d76f4c2e 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/IterableConstructors.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/IterableConstructors.kt @@ -7,7 +7,6 @@ import org.utbot.framework.plugin.api.UtExecutableCallModel import org.utbot.framework.plugin.api.UtStatementModel import org.utbot.framework.plugin.api.util.booleanClassId import org.utbot.framework.plugin.api.util.id -import org.utbot.framework.plugin.api.util.jClass import org.utbot.framework.plugin.api.util.objectClassId import org.utbot.framework.util.valueToClassId @@ -30,8 +29,7 @@ internal class CollectionConstructor : UtAssembleModelConstructorBase() { instantiationChain += UtExecutableCallModel( instance = null, ConstructorId(classId, emptyList()), - emptyList(), - this + emptyList() ) val addMethodId = MethodId(classId, "add", booleanClassId, listOf(objectClassId)) @@ -56,8 +54,7 @@ internal class MapConstructor : UtAssembleModelConstructorBase() { instantiationChain += UtExecutableCallModel( instance = null, ConstructorId(classId, emptyList()), - emptyList(), - this + emptyList() ) val putMethodId = MethodId(classId, "put", objectClassId, listOf(objectClassId, objectClassId)) diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/MockValueConstructor.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/MockValueConstructor.kt index 2c2126de65..413684ea22 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/MockValueConstructor.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/MockValueConstructor.kt @@ -358,9 +358,16 @@ class MockValueConstructor( private fun constructFromAssembleModel(assembleModel: UtAssembleModel): Any { constructedObjects[assembleModel]?.let { return it } - assembleModel.allStatementsChain.forEach { statementModel -> + val instantiationExecutableCall = assembleModel.instantiationChain.single() as UtExecutableCallModel + val result = updateWithExecutableCallModel(instantiationExecutableCall) + checkNotNull(result) { + "Tracked instance can't be null for call ${instantiationExecutableCall.executable} in model $assembleModel" + } + constructedObjects[assembleModel] = result + + assembleModel.modificationsChain.forEach { statementModel -> when (statementModel) { - is UtExecutableCallModel -> updateWithExecutableCallModel(statementModel, assembleModel) + is UtExecutableCallModel -> updateWithExecutableCallModel(statementModel) is UtDirectSetFieldModel -> updateWithDirectSetFieldModel(statementModel) } } @@ -398,12 +405,13 @@ class MockValueConstructor( } /** - * Updates instance state with [UtExecutableCallModel] invocation. + * Updates instance state with [callModel] invocation. + * + * @return the result of [callModel] invocation */ private fun updateWithExecutableCallModel( callModel: UtExecutableCallModel, - assembleModel: UtAssembleModel, - ) { + ): Any? { val executable = callModel.executable val instanceValue = callModel.instance?.let { value(it) } val params = callModel.params.map { value(it) } @@ -413,15 +421,7 @@ class MockValueConstructor( is ConstructorId -> executable.call(params) } - // Ignore result if returnId is null. Otherwise add it to instance cache. - callModel.returnValue?.let { - checkNotNull(result) { "Tracked instance can't be null for call $executable in model $assembleModel" } - - //If statement is final instantiating, add result to constructed objects cache - if (callModel == assembleModel.finalInstantiationModel) { - constructedObjects[assembleModel] = result - } - } + return result } /** diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/OptionalConstructors.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/OptionalConstructors.kt index d8e15a20b2..7f82d9dad8 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/OptionalConstructors.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/OptionalConstructors.kt @@ -38,19 +38,17 @@ internal sealed class OptionalConstructorBase : UtAssembleModelConstructorBase() "Can't cast $valueToConstructFrom to ${classId.jClass} in $this assemble constructor." } - modificationChain += if (!isPresent.call(valueToConstructFrom)) { + instantiationChain += if (!isPresent.call(valueToConstructFrom)) { UtExecutableCallModel( instance = null, emptyMethodId, - emptyList(), - this + emptyList() ) } else { UtExecutableCallModel( instance = null, ofMethodId, - listOf(internalConstructor.construct(getter.call(valueToConstructFrom), elementClassId)), - this + listOf(internalConstructor.construct(getter.call(valueToConstructFrom), elementClassId)) ) } } diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/PrimitiveWrapperConstructor.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/PrimitiveWrapperConstructor.kt index 4793d6377a..29680feb24 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/PrimitiveWrapperConstructor.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/PrimitiveWrapperConstructor.kt @@ -22,8 +22,7 @@ internal class PrimitiveWrapperConstructor : UtAssembleModelConstructorBase() { instantiationChain += UtExecutableCallModel( null, constructorId(classId, classId.unbox()), - listOf(UtPrimitiveModel(valueToConstructFrom)), - this + listOf(UtPrimitiveModel(valueToConstructFrom)) ) } } diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/UtAssembleModelConstructors.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/UtAssembleModelConstructors.kt index 9a335798a6..33cc6bf4fb 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/UtAssembleModelConstructors.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/UtAssembleModelConstructors.kt @@ -7,7 +7,6 @@ import org.utbot.framework.plugin.api.util.jClass import org.utbot.framework.plugin.api.util.primitiveWrappers import org.utbot.framework.plugin.api.util.voidWrapperClassId import org.utbot.framework.util.nextModelName -import java.util.concurrent.CopyOnWriteArrayList private val predefinedConstructors = mutableMapOf, () -> UtAssembleModelConstructorBase>( /** diff --git a/utbot-framework/src/main/kotlin/org/utbot/fuzzer/FallbackModelProvider.kt b/utbot-framework/src/main/kotlin/org/utbot/fuzzer/FallbackModelProvider.kt index 1244cd8851..ad23b7bf43 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/fuzzer/FallbackModelProvider.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/fuzzer/FallbackModelProvider.kt @@ -102,7 +102,7 @@ open class FallbackModelProvider( chain ) chain.add( - UtExecutableCallModel(model, defaultConstructor.executableId, listOf(), model) + UtExecutableCallModel(model, defaultConstructor.executableId, listOf()) ) model } diff --git a/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/RandomExtensions.kt b/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/RandomExtensions.kt index c9eb21f9b5..c665f0bbf6 100644 --- a/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/RandomExtensions.kt +++ b/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/RandomExtensions.kt @@ -1,10 +1,6 @@ package org.utbot.fuzzer import kotlin.random.Random -import org.utbot.framework.plugin.api.ConstructorId -import org.utbot.framework.plugin.api.UtAssembleModel -import org.utbot.framework.plugin.api.UtExecutableCallModel -import org.utbot.framework.plugin.api.UtStatementModel /** * Chooses a random value using frequencies. diff --git a/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/objects/AssembleModelUtils.kt b/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/objects/AssembleModelUtils.kt index d030b97f90..1e022c82c9 100644 --- a/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/objects/AssembleModelUtils.kt +++ b/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/objects/AssembleModelUtils.kt @@ -18,7 +18,7 @@ fun ModelProvider.assembleModel(id: Int, constructorId: ConstructorId, params: L instantiationChain = instantiationChain, modificationsChain = mutableListOf() ).apply { - instantiationChain += UtExecutableCallModel(null, constructorId, params.map { it.model }, this) + instantiationChain += UtExecutableCallModel(null, constructorId, params.map { it.model }) }.fuzzed { summary = "%var% = ${constructorId.classId.simpleName}(${constructorId.parameters.joinToString { it.simpleName }})" } diff --git a/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/providers/CollectionModelProvider.kt b/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/providers/CollectionModelProvider.kt index 8d71c0bca5..0a9c242e05 100644 --- a/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/providers/CollectionModelProvider.kt +++ b/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/providers/CollectionModelProvider.kt @@ -100,7 +100,7 @@ class CollectionModelProvider( "${init.classId.name}${init.parameters}#" + genId.toString(16), instantiationChain ).apply { - instantiationChain += UtExecutableCallModel(null, init, params, this) + instantiationChain += UtExecutableCallModel(null, init, params) } } } \ No newline at end of file diff --git a/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/providers/DateConstantModelProvider.kt b/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/providers/DateConstantModelProvider.kt index c712bf4540..1b33e977d1 100644 --- a/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/providers/DateConstantModelProvider.kt +++ b/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/providers/DateConstantModelProvider.kt @@ -143,7 +143,7 @@ class DateConstantModelProvider( instantiationChain ).apply { instantiationChain += UtExecutableCallModel( - simpleDateFormatModel, dateFormatParse, listOf(UtPrimitiveModel(dateString)), returnValue = this + simpleDateFormatModel, dateFormatParse, listOf(UtPrimitiveModel(dateString)) ) }.fuzzed { summary = "%var% = $dateFormatParse($stringClassId)" @@ -168,7 +168,7 @@ class DateConstantModelProvider( modificationsChain ).apply { instantiationChain += UtExecutableCallModel( - instance = null, formatStringConstructor, listOf(formatModel), returnValue = this + instance = null, formatStringConstructor, listOf(formatModel) ) modificationsChain += UtExecutableCallModel( instance = this, formatSetLenient, listOf(UtPrimitiveModel(false)) diff --git a/utbot-fuzzers/src/test/kotlin/org/utbot/framework/plugin/api/ModelProviderTest.kt b/utbot-fuzzers/src/test/kotlin/org/utbot/framework/plugin/api/ModelProviderTest.kt index b7d0320f9d..4671e7a0a9 100644 --- a/utbot-fuzzers/src/test/kotlin/org/utbot/framework/plugin/api/ModelProviderTest.kt +++ b/utbot-fuzzers/src/test/kotlin/org/utbot/framework/plugin/api/ModelProviderTest.kt @@ -206,10 +206,8 @@ class ModelProviderTest { assertTrue(models[0]!!.all { it is UtAssembleModel && it.classId == classId }) models[0]!!.filterIsInstance().forEachIndexed { index, model -> - assertEquals(1, model.instantiationChain.size) - val stm = model.instantiationChain[0] - assertTrue(stm is UtExecutableCallModel) - stm as UtExecutableCallModel + assertEquals(1, model.instantiationStatement.size) + val stm = model.instantiationStatement[0] val paramCountInConstructorAsTheyListed = index + 1 assertEquals(paramCountInConstructorAsTheyListed, stm.params.size) } @@ -249,10 +247,9 @@ class ModelProviderTest { assertEquals(1, models.size) assertTrue(models[0]!!.isNotEmpty()) - val chain = (models[0]!![0] as UtAssembleModel).instantiationChain + val chain = (models[0]!![0] as UtAssembleModel).instantiationStatement assertEquals(1, chain.size) - assertTrue(chain[0] is UtExecutableCallModel) - (chain[0] as UtExecutableCallModel).params.forEach { + chain[0].params.forEach { assertEquals(intClassId, it.classId) } } @@ -369,15 +366,14 @@ class ModelProviderTest { assertEquals(1, result[0]!!.size) assertInstanceOf(UtAssembleModel::class.java, result[0]!![0]) assertEquals(A::class.java.id, result[0]!![0].classId) - (result[0]!![0] as UtAssembleModel).instantiationChain.forEach { - assertTrue(it is UtExecutableCallModel) - assertEquals(1, (it as UtExecutableCallModel).params.size) + (result[0]!![0] as UtAssembleModel).instantiationStatement.forEach { + assertEquals(1, it.params.size) val objectParamInConstructor = it.params[0] assertInstanceOf(UtAssembleModel::class.java, objectParamInConstructor) val innerAssembledModel = objectParamInConstructor as UtAssembleModel assertEquals(Any::class.java.id, innerAssembledModel.classId) - assertEquals(1, innerAssembledModel.instantiationChain.size) - val objectCreation = innerAssembledModel.instantiationChain.first() as UtExecutableCallModel + assertEquals(1, innerAssembledModel.instantiationStatement.size) + val objectCreation = innerAssembledModel.instantiationStatement.first() assertEquals(0, objectCreation.params.size) assertInstanceOf(ConstructorId::class.java, objectCreation.executable) } @@ -399,13 +395,13 @@ class ModelProviderTest { assertEquals(1, result.size) assertEquals(1, result[0]!!.size) val outerModel = result[0]!![0] as UtAssembleModel - outerModel.instantiationChain.forEach { - val constructorParameters = (it as UtExecutableCallModel).params + outerModel.instantiationStatement.forEach { + val constructorParameters = it.params assertEquals(1, constructorParameters.size) val innerModel = (constructorParameters[0] as UtAssembleModel) assertEquals(MyA::class.java.id, innerModel.classId) - assertEquals(1, innerModel.instantiationChain.size) - val innerConstructorParameters = innerModel.instantiationChain[0] as UtExecutableCallModel + assertEquals(1, innerModel.instantiationStatement.size) + val innerConstructorParameters = innerModel.instantiationStatement[0] assertEquals(1, innerConstructorParameters.params.size) assertInstanceOf(UtNullModel::class.java, innerConstructorParameters.params[0]) } @@ -441,13 +437,13 @@ class ModelProviderTest { assertEquals(1, result.size) assertEquals(1, result[0]!!.size) val outerModel = result[0]!![0] as UtAssembleModel - outerModel.instantiationChain.forEach { - val constructorParameters = (it as UtExecutableCallModel).params + outerModel.instantiationStatement.forEach { + val constructorParameters = it.params assertEquals(1, constructorParameters.size) val innerModel = (constructorParameters[0] as UtAssembleModel) assertEquals(Inner::class.java.id, innerModel.classId) - assertEquals(1, innerModel.instantiationChain.size) - val innerConstructorParameters = innerModel.instantiationChain[0] as UtExecutableCallModel + assertEquals(1, innerModel.instantiationStatement.size) + val innerConstructorParameters = innerModel.instantiationStatement[0] assertEquals(2, innerConstructorParameters.params.size) assertTrue(innerConstructorParameters.params.all { param -> param is UtPrimitiveModel }) assertEquals(intClassId, innerConstructorParameters.params[0].classId) @@ -543,7 +539,7 @@ class ModelProviderTest { for (model in models) { val outerModel = (model as? UtAssembleModel) - ?.finalInstantiationModel as? UtExecutableCallModel + ?.instantiationStatement as? UtExecutableCallModel ?: fail("No final instantiation model found for the outer class") for (param in outerModel.params) { when (param) { @@ -551,7 +547,7 @@ class ModelProviderTest { assertEquals(expectedIds[param.value], param.id) } is UtAssembleModel -> { - for (enumParam in (param.finalInstantiationModel as UtExecutableCallModel).params) { + for (enumParam in (param.instantiationStatement as UtExecutableCallModel).params) { enumParam as UtEnumConstantModel assertEquals(expectedIds[enumParam.value], enumParam.id) } From 8e0c6eaad463daf81499ffd4d50841299f0bc184 Mon Sep 17 00:00:00 2001 From: Sergey Pospelov Date: Mon, 19 Sep 2022 18:07:53 +0300 Subject: [PATCH 3/9] Refactor: change `instantiationChain` to `instantiationCall` and rewrite `UtAssembleModel` constructor --- .../org/utbot/framework/plugin/api/Api.kt | 49 +++++++++++---- .../models/ModelsIdEqualityChecker.kt | 2 +- .../org/utbot/engine/CollectionWrappers.kt | 22 +++---- .../kotlin/org/utbot/engine/ObjectWrappers.kt | 22 +++---- .../org/utbot/engine/OptionalWrapper.kt | 8 +-- .../main/kotlin/org/utbot/engine/Resolver.kt | 7 +-- .../utbot/engine/SecurityManagerWrapper.kt | 13 ++-- .../kotlin/org/utbot/engine/StreamWrappers.kt | 30 ++++----- .../main/kotlin/org/utbot/engine/Strings.kt | 33 ++++------ .../org/utbot/engine/ValueConstructor.kt | 2 +- .../assemble/AssembleModelGenerator.kt | 53 +++++++++------- .../assemble/AssemblePrimitiveWrapper.kt | 3 +- .../constructor/tree/CgVariableConstructor.kt | 4 +- .../concrete/IterableConstructors.kt | 61 +++++++++++-------- .../concrete/MockValueConstructor.kt | 2 +- .../concrete/OptionalConstructors.kt | 30 ++++----- .../concrete/PrimitiveWrapperConstructor.kt | 21 ++++--- .../concrete/UtAssembleModelConstructors.kt | 27 ++++---- .../framework/minimization/Minimization.kt | 4 +- .../org/utbot/fuzzer/FallbackModelProvider.kt | 9 +-- .../infrastructure/UtModelTestCaseChecker.kt | 2 +- .../fuzzer/objects/AssembleModelUtils.kt | 9 +-- .../providers/CollectionModelProvider.kt | 8 +-- .../providers/DateConstantModelProvider.kt | 25 +++----- 24 files changed, 228 insertions(+), 218 deletions(-) diff --git a/utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/Api.kt b/utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/Api.kt index a2de8d5403..f04983fb5e 100644 --- a/utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/Api.kt +++ b/utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/Api.kt @@ -471,26 +471,52 @@ data class UtArrayModel( /** * Model for complex objects with assemble instructions. * - * @param instantiationChain is a chain of [UtStatementModel] to instantiate represented object - * @param modificationsChain is a chain of [UtStatementModel] to construct object state + * The default constructor is made private to enforce using a safe constructor. + * + * @param instantiationCall is an [UtExecutableCallModel] to instantiate represented object. + * @param modificationsChain is a chain of [UtStatementModel] to construct object state. */ -data class UtAssembleModel( +data class UtAssembleModel private constructor( override val id: Int?, override val classId: ClassId, override val modelName: String, - val instantiationChain: List = emptyList(), - val modificationsChain: List = emptyList(), - val origin: UtCompositeModel? = null + val instantiationCall: UtExecutableCallModel, + val modificationsChain: List, + val origin: UtCompositeModel? ) : UtReferenceModel(id, classId, modelName) { - val allStatementsChain - get() = instantiationChain + modificationsChain - val finalInstantiationModel - get() = instantiationChain.lastOrNull() + + /** + * Creates a new [UtAssembleModel]. + * + * Please note, that it's the caller responsibility to properly cache [UtModel]s to prevent an infinite recursion. + * The order of the calling: + * 1. [instantiationCall] + * 2. [constructor] + * 3. [modificationsChainProvider]. Possible caching should be made at the beginning of this method. + * + * @param instantiationCall defines the single instruction, which provides a [UtAssembleModel]. It could be a + * constructor or a method of another class, which returns the object of the [classId] type. + * + * @param modificationsChainProvider used for creating modifying statements. Its receiver corresponds to newly + * created [UtAssembleModel], so you can use it for caching and for creating [UtExecutableCallModel]s with it + * as [UtExecutableCallModel.instance]. + */ + constructor( + id: Int?, + classId: ClassId, + modelName: String, + instantiationCall: UtExecutableCallModel, + origin: UtCompositeModel? = null, + modificationsChainProvider: UtAssembleModel.() -> List = { emptyList() } + ) : this(id, classId, modelName, instantiationCall, mutableListOf(), origin) { + val modificationChainStatements = modificationsChainProvider() + (modificationsChain as MutableList).addAll(modificationChainStatements) + } override fun toString() = withToStringThreadLocalReentrancyGuard { buildString { append("UtAssembleModel(${classId.simpleName} $modelName) ") - append(instantiationChain.joinToString(" ")) + append(instantiationCall) if (modificationsChain.isNotEmpty()) { append(" ") append(modificationsChain.joinToString(" ")) @@ -562,7 +588,6 @@ sealed class UtStatementModel( * Step of assemble instruction that calls executable. * * Contains executable to call, call parameters and an instance model before call. - * Return value is used for tracking objects and call others methods with these tracking objects as parameters. */ data class UtExecutableCallModel( override val instance: UtReferenceModel?, diff --git a/utbot-framework-test/src/test/kotlin/org/utbot/examples/models/ModelsIdEqualityChecker.kt b/utbot-framework-test/src/test/kotlin/org/utbot/examples/models/ModelsIdEqualityChecker.kt index 45a9bad8c7..2a13e9a976 100644 --- a/utbot-framework-test/src/test/kotlin/org/utbot/examples/models/ModelsIdEqualityChecker.kt +++ b/utbot-framework-test/src/test/kotlin/org/utbot/examples/models/ModelsIdEqualityChecker.kt @@ -129,7 +129,7 @@ internal class ModelsIdEqualityChecker : UtModelTestCaseChecker( private fun UtReferenceModel.findFieldId(): Int? { this as UtAssembleModel - val fieldModel = this.allStatementsChain + val fieldModel = this.modificationsChain .filterIsInstance() .single() .fieldModel diff --git a/utbot-framework/src/main/kotlin/org/utbot/engine/CollectionWrappers.kt b/utbot-framework/src/main/kotlin/org/utbot/engine/CollectionWrappers.kt index 70689f922e..40add8087f 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/engine/CollectionWrappers.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/engine/CollectionWrappers.kt @@ -119,21 +119,15 @@ abstract class BaseContainerWrapper(containerClassName: String) : BaseOverridden val classId = chooseClassIdWithConstructor(wrapper.type.sootClass.id) - val instantiationChain = mutableListOf() - val modificationsChain = mutableListOf() - - UtAssembleModel(addr, classId, modelName, instantiationChain, modificationsChain) - .apply { - instantiationChain += UtExecutableCallModel( - instance = null, - executable = constructorId(classId), - params = emptyList() - ) + val instantiationCall = UtExecutableCallModel( + instance = null, + executable = constructorId(classId), + params = emptyList() + ) - modificationsChain += parameterModels.map { - UtExecutableCallModel(this, modificationMethodId, it) - } - } + UtAssembleModel(addr, classId, modelName, instantiationCall) { + parameterModels.map { UtExecutableCallModel(this, modificationMethodId, it) } + } } /** diff --git a/utbot-framework/src/main/kotlin/org/utbot/engine/ObjectWrappers.kt b/utbot-framework/src/main/kotlin/org/utbot/engine/ObjectWrappers.kt index 9a6bdb742e..1ea60aa140 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/engine/ObjectWrappers.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/engine/ObjectWrappers.kt @@ -241,17 +241,15 @@ data class ThrowableWrapper(val throwable: Throwable) : WrapperInterface { val addr = resolver.holder.concreteAddr(wrapper.addr) val modelName = nextModelName(throwable.javaClass.simpleName.decapitalize()) - val instantiationChain = mutableListOf() - return UtAssembleModel(addr, classId, modelName, instantiationChain) - .apply { - instantiationChain += when (val message = throwable.message) { - null -> UtExecutableCallModel(null, constructorId(classId), emptyList()) - else -> UtExecutableCallModel( - null, - constructorId(classId, stringClassId), - listOf(UtPrimitiveModel(message)) - ) - } - } + val instantiationCall = when (val message = throwable.message) { + null -> UtExecutableCallModel(null, constructorId(classId), emptyList()) + else -> UtExecutableCallModel( + null, + constructorId(classId, stringClassId), + listOf(UtPrimitiveModel(message)) + ) + } + + return UtAssembleModel(addr, classId, modelName, instantiationCall) } } \ No newline at end of file diff --git a/utbot-framework/src/main/kotlin/org/utbot/engine/OptionalWrapper.kt b/utbot-framework/src/main/kotlin/org/utbot/engine/OptionalWrapper.kt index 627c1faf5c..7ce2226d14 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/engine/OptionalWrapper.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/engine/OptionalWrapper.kt @@ -90,12 +90,8 @@ class OptionalWrapper(private val utOptionalClass: UtOptionalClass) : BaseOverri val addr = holder.concreteAddr(wrapper.addr) val modelName = nextModelName(baseModelName) - val instantiationChain = mutableListOf() - val modificationsChain = mutableListOf() - return UtAssembleModel(addr, classId, modelName, instantiationChain, modificationsChain) - .apply { - instantiationChain += instantiationFactoryCallModel(classId, wrapper) - } + val instantiationCall = instantiationFactoryCallModel(classId, wrapper) + return UtAssembleModel(addr, classId, modelName, instantiationCall) } private fun Resolver.instantiationFactoryCallModel(classId: ClassId, wrapper: ObjectValue) : UtExecutableCallModel { diff --git a/utbot-framework/src/main/kotlin/org/utbot/engine/Resolver.kt b/utbot-framework/src/main/kotlin/org/utbot/engine/Resolver.kt index 8164ef0222..3b1cc4bbb8 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/engine/Resolver.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/engine/Resolver.kt @@ -550,11 +550,8 @@ class Resolver( val baseModelName = primitiveClassId.name val constructorId = constructorId(classId, primitiveClassId) val valueModel = fields[FieldId(classId, "value")] ?: primitiveClassId.defaultValueModel() - val instantiationChain = mutableListOf() - UtAssembleModel(addr, classId, nextModelName(baseModelName), instantiationChain) - .apply { - instantiationChain += UtExecutableCallModel(null, constructorId, listOf(valueModel)) - } + val instantiationCall = UtExecutableCallModel(null, constructorId, listOf(valueModel)) + UtAssembleModel(addr, classId, nextModelName(baseModelName), instantiationCall) } } diff --git a/utbot-framework/src/main/kotlin/org/utbot/engine/SecurityManagerWrapper.kt b/utbot-framework/src/main/kotlin/org/utbot/engine/SecurityManagerWrapper.kt index 90a0be0d1f..ec686b32aa 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/engine/SecurityManagerWrapper.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/engine/SecurityManagerWrapper.kt @@ -2,9 +2,10 @@ package org.utbot.engine import org.utbot.engine.overrides.security.UtSecurityManager import org.utbot.framework.plugin.api.UtAssembleModel +import org.utbot.framework.plugin.api.UtExecutableCallModel import org.utbot.framework.plugin.api.UtModel -import org.utbot.framework.plugin.api.UtStatementModel import org.utbot.framework.plugin.api.classId +import org.utbot.framework.plugin.api.util.executableId import org.utbot.framework.util.nextModelName import soot.Scene import soot.SootClass @@ -27,9 +28,13 @@ class SecurityManagerWrapper : BaseOverriddenWrapper(utSecurityManagerClass.name val addr = holder.concreteAddr(wrapper.addr) val modelName = nextModelName(baseModelName) - val instantiationChain = mutableListOf() - val modificationChain = mutableListOf() - return UtAssembleModel(addr, classId, modelName, instantiationChain, modificationChain) + val instantiationCall = UtExecutableCallModel( + null, + System::getSecurityManager.executableId, + emptyList() + ) + + return UtAssembleModel(addr, classId, modelName, instantiationCall) } companion object { diff --git a/utbot-framework/src/main/kotlin/org/utbot/engine/StreamWrappers.kt b/utbot-framework/src/main/kotlin/org/utbot/engine/StreamWrappers.kt index d66d92720a..992e3ac694 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/engine/StreamWrappers.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/engine/StreamWrappers.kt @@ -61,23 +61,19 @@ abstract class StreamWrapper( val modelName = nextModelName(baseModelName) val parametersArrayModel = resolveElementsAsArrayModel(wrapper) - val instantiationChain = mutableListOf() - val modificationsChain = emptyList() - - UtAssembleModel(addr, utStreamClass.overriddenStreamClassId, modelName, instantiationChain, modificationsChain) - .apply { - val (builder, params) = if (parametersArrayModel == null || parametersArrayModel.length == 0) { - streamEmptyMethodId to emptyList() - } else { - streamOfMethodId to listOf(parametersArrayModel) - } - - instantiationChain += UtExecutableCallModel( - instance = null, - executable = builder, - params = params - ) - } + val (builder, params) = if (parametersArrayModel == null || parametersArrayModel.length == 0) { + streamEmptyMethodId to emptyList() + } else { + streamOfMethodId to listOf(parametersArrayModel) + } + + val instantiationCall = UtExecutableCallModel( + instance = null, + executable = builder, + params = params + ) + + UtAssembleModel(addr, utStreamClass.overriddenStreamClassId, modelName, instantiationCall) } override fun chooseClassIdWithConstructor(classId: ClassId): ClassId = error("No constructor for Stream") diff --git a/utbot-framework/src/main/kotlin/org/utbot/engine/Strings.kt b/utbot-framework/src/main/kotlin/org/utbot/engine/Strings.kt index 355cff5d46..ea19138160 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/engine/Strings.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/engine/Strings.kt @@ -179,16 +179,12 @@ class StringWrapper : BaseOverriddenWrapper(utStringClass.name) { val charValues = CharArray(length) { (values.stores[it] as UtPrimitiveModel).value as Char } val stringModel = UtPrimitiveModel(String(charValues)) - val instantiationChain = mutableListOf() - val modificationsChain = mutableListOf() - return UtAssembleModel(addr, classId, modelName, instantiationChain, modificationsChain) - .apply { - instantiationChain += UtExecutableCallModel( - instance = null, - constructorId(classId, STRING_TYPE.classId), - listOf(stringModel) - ) - } + val instantiationCall = UtExecutableCallModel( + instance = null, + constructorId(classId, STRING_TYPE.classId), + listOf(stringModel) + ) + return UtAssembleModel(addr, classId, modelName, instantiationCall) } } @@ -332,18 +328,13 @@ sealed class UtAbstractStringBuilderWrapper(className: String) : BaseOverriddenW val charValues = CharArray(length) { (values.stores[it] as UtPrimitiveModel).value as Char } val stringModel = UtPrimitiveModel(String(charValues)) - - val instantiationChain = mutableListOf() - val modificationsChain = mutableListOf() val constructorId = constructorId(wrapper.type.classId, STRING_TYPE.classId) - return UtAssembleModel(addr, wrapper.type.classId, modelName, instantiationChain, modificationsChain) - .apply { - instantiationChain += UtExecutableCallModel( - instance = null, - constructorId, - listOf(stringModel) - ) - } + val instantiationChain = UtExecutableCallModel( + instance = null, + constructorId, + listOf(stringModel) + ) + return UtAssembleModel(addr, wrapper.type.classId, modelName, instantiationChain) } private val SootClass.valueField: SootField diff --git a/utbot-framework/src/main/kotlin/org/utbot/engine/ValueConstructor.kt b/utbot-framework/src/main/kotlin/org/utbot/engine/ValueConstructor.kt index a620ca9a87..ff436d10ff 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/engine/ValueConstructor.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/engine/ValueConstructor.kt @@ -328,7 +328,7 @@ class ValueConstructor { private fun constructFromAssembleModel(assembleModel: UtAssembleModel): Any { constructedObjects[assembleModel]?.let { return it } - val instantiationExecutableCall = assembleModel.instantiationChain.single() as UtExecutableCallModel + val instantiationExecutableCall = assembleModel.instantiationCall val result = updateWithExecutableCallModel(instantiationExecutableCall) checkNotNull(result) { "Tracked instance can't be null for call ${instantiationExecutableCall.executable} in model $assembleModel" diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/assemble/AssembleModelGenerator.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/assemble/AssembleModelGenerator.kt index 3ef1f52732..5cb26ff8b3 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/assemble/AssembleModelGenerator.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/assemble/AssembleModelGenerator.kt @@ -234,24 +234,20 @@ class AssembleModelGenerator(private val methodPackageName: String) { try { val modelName = nextModelName(compositeModel.classId.jClass.simpleName.decapitalize()) - val instantiationChain = mutableListOf() - val modificationsChain = mutableListOf() + val constructorId = findBestConstructorOrNull(compositeModel) + ?: throw AssembleException("No default constructor to instantiate an object of the class ${compositeModel.id}") + + val constructorInfo = constructorAnalyzer.analyze(constructorId) + + val instantiationCall = constructorCall(compositeModel, constructorInfo) return UtAssembleModel( compositeModel.id, compositeModel.classId, modelName, - instantiationChain, - modificationsChain, + instantiationCall, compositeModel - ).apply { - - val constructorId = findBestConstructorOrNull(compositeModel) - ?: throw AssembleException("No default constructor to instantiate an object of the class $classId") - - val constructorInfo = constructorAnalyzer.analyze(constructorId) - + ) { instantiatedModels[compositeModel] = this - instantiationChain += constructorCall(compositeModel, constructorInfo) compositeModel.fields.forEach { (fieldId, fieldModel) -> if (fieldId.isStatic) { @@ -274,7 +270,7 @@ class AssembleModelGenerator(private val methodPackageName: String) { } } - modificationsChain += callChain.toList() + callChain.toList() } } catch (e: AssembleException) { instantiatedModels.remove(compositeModel) @@ -288,17 +284,16 @@ class AssembleModelGenerator(private val methodPackageName: String) { private fun assembleAssembleModel(modelBefore: UtAssembleModel): UtModel { instantiatedModels[modelBefore]?.let { return it } - val instantiationChain = mutableListOf() - val modificationChain = mutableListOf() - return modelBefore.copy( - instantiationChain = instantiationChain, - modificationsChain = modificationChain, + return UtAssembleModel( + modelBefore.id, + modelBefore.classId, + modelBefore.modelName, + assembleExecutableCallModel(modelBefore.instantiationCall), + modelBefore.origin ).apply { instantiatedModels[modelBefore] = this - - instantiationChain += modelBefore.instantiationChain.map { assembleStatementModel(it) } - modificationChain += modelBefore.modificationsChain.map { assembleStatementModel(it) } + modelBefore.modificationsChain.map { assembleStatementModel(it) } } } @@ -306,10 +301,22 @@ class AssembleModelGenerator(private val methodPackageName: String) { * Assembles internal structure of [UtStatementModel]. */ private fun assembleStatementModel(statementModel: UtStatementModel): UtStatementModel = when (statementModel) { - is UtExecutableCallModel -> statementModel.copy(params = statementModel.params.map { assembleModel(it) }) - is UtDirectSetFieldModel -> statementModel.copy(fieldModel = assembleModel(statementModel.fieldModel)) + is UtExecutableCallModel -> assembleExecutableCallModel(statementModel) + is UtDirectSetFieldModel -> assembleDirectSetFieldModel(statementModel) } + private fun assembleDirectSetFieldModel(statementModel: UtDirectSetFieldModel) = + statementModel.copy( + instance = statementModel.instance.let { assembleModel(it) as UtReferenceModel }, + fieldModel = assembleModel(statementModel.fieldModel) + ) + + private fun assembleExecutableCallModel(statementModel: UtExecutableCallModel) = + statementModel.copy( + instance = statementModel.instance?.let { assembleModel(it) as UtReferenceModel }, + params = statementModel.params.map { assembleModel(it) } + ) + /** * Assembles internal structure of [UtCompositeModel] if it represents a mock. */ diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/assemble/AssemblePrimitiveWrapper.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/assemble/AssemblePrimitiveWrapper.kt index fcbd79fff3..4c6a5891fc 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/assemble/AssemblePrimitiveWrapper.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/assemble/AssemblePrimitiveWrapper.kt @@ -43,7 +43,6 @@ fun assemble(model: UtPrimitiveModel): UtAssembleModel { id = null, classId = assembledModelType, modelName = modelType.canonicalName, - instantiationChain = listOf(constructorCallModel), - modificationsChain = emptyList(), + instantiationCall = constructorCallModel, ) } \ No newline at end of file diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/tree/CgVariableConstructor.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/tree/CgVariableConstructor.kt index c0a8b2a029..5f58d67a1d 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/tree/CgVariableConstructor.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/tree/CgVariableConstructor.kt @@ -201,7 +201,7 @@ internal class CgVariableConstructor(val context: CgContext) : } private fun constructAssemble(model: UtAssembleModel, baseName: String?): CgValue { - val instantiationExecutableCall = model.instantiationChain.single() as UtExecutableCallModel + val instantiationExecutableCall = model.instantiationCall processInstantiationStatement(model, instantiationExecutableCall, baseName) for (statementModel in model.modificationsChain) { @@ -236,7 +236,7 @@ internal class CgVariableConstructor(val context: CgContext) : // Don't use redundant constructors for primitives and String val initExpr = if (isPrimitiveWrapperOrString(type)) cgLiteralForWrapper(params) else cgCall newVar(type, model, baseName) { initExpr } - .takeIf { executableCall == model.finalInstantiationModel } + .takeIf { executableCall == model.instantiationCall } ?.also { valueByModelId[model.id] = it } } diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/IterableConstructors.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/IterableConstructors.kt index b9d76f4c2e..2cb45038dd 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/IterableConstructors.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/IterableConstructors.kt @@ -1,5 +1,6 @@ package org.utbot.framework.concrete +import org.utbot.framework.plugin.api.ClassId import org.utbot.framework.plugin.api.ConstructorId import org.utbot.framework.plugin.api.MethodId import org.utbot.framework.plugin.api.UtAssembleModel @@ -11,55 +12,61 @@ import org.utbot.framework.plugin.api.util.objectClassId import org.utbot.framework.util.valueToClassId internal class CollectionConstructor : UtAssembleModelConstructorBase() { - override fun UtAssembleModel.modifyChains( + override fun UtAssembleModel.provideModificationChain( internalConstructor: UtModelConstructorInterface, - instantiationChain: MutableList, - modificationChain: MutableList, - valueToConstructFrom: Any - ) { + value: Any + ): List { @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN") - valueToConstructFrom as java.util.Collection<*> + value as java.util.Collection<*> // If [valueToConstructFrom] constructed incorrectly (some inner transient fields are null, etc.) this may fail. // This value will be constructed as UtCompositeModel. - val models = valueToConstructFrom.map { internalConstructor.construct(it, valueToClassId(it)) } + val models = value.map { internalConstructor.construct(it, valueToClassId(it)) } - val classId = valueToConstructFrom::class.java.id + val classId = value::class.java.id - instantiationChain += UtExecutableCallModel( + val addMethodId = MethodId(classId, "add", booleanClassId, listOf(objectClassId)) + + return models.map { UtExecutableCallModel(this, addMethodId, listOf(it)) } + } + + override fun provideInstantiationCall( + internalConstructor: UtModelConstructorInterface, + value: Any, + classId: ClassId + ): UtExecutableCallModel = + UtExecutableCallModel( instance = null, ConstructorId(classId, emptyList()), emptyList() ) - - val addMethodId = MethodId(classId, "add", booleanClassId, listOf(objectClassId)) - - modificationChain += models.map { UtExecutableCallModel(this, addMethodId, listOf(it)) } - } } internal class MapConstructor : UtAssembleModelConstructorBase() { - override fun UtAssembleModel.modifyChains( + override fun provideInstantiationCall( internalConstructor: UtModelConstructorInterface, - instantiationChain: MutableList, - modificationChain: MutableList, - valueToConstructFrom: Any - ) { - valueToConstructFrom as java.util.AbstractMap<*, *> - - val keyToValueModels = valueToConstructFrom.map { (key, value) -> - internalConstructor.run { construct(key, valueToClassId(key)) to construct(value, valueToClassId(value)) } - } - - instantiationChain += UtExecutableCallModel( + value: Any, + classId: ClassId + ): UtExecutableCallModel = + UtExecutableCallModel( instance = null, ConstructorId(classId, emptyList()), emptyList() ) + override fun UtAssembleModel.provideModificationChain( + internalConstructor: UtModelConstructorInterface, + value: Any + ): List { + value as java.util.AbstractMap<*, *> + + val keyToValueModels = value.map { (key, value) -> + internalConstructor.run { construct(key, valueToClassId(key)) to construct(value, valueToClassId(value)) } + } + val putMethodId = MethodId(classId, "put", objectClassId, listOf(objectClassId, objectClassId)) - modificationChain += keyToValueModels.map { (key, value) -> + return keyToValueModels.map { (key, value) -> UtExecutableCallModel(this, putMethodId, listOf(key, value)) } } diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/MockValueConstructor.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/MockValueConstructor.kt index 413684ea22..182c0c2f9d 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/MockValueConstructor.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/MockValueConstructor.kt @@ -358,7 +358,7 @@ class MockValueConstructor( private fun constructFromAssembleModel(assembleModel: UtAssembleModel): Any { constructedObjects[assembleModel]?.let { return it } - val instantiationExecutableCall = assembleModel.instantiationChain.single() as UtExecutableCallModel + val instantiationExecutableCall = assembleModel.instantiationCall val result = updateWithExecutableCallModel(instantiationExecutableCall) checkNotNull(result) { "Tracked instance can't be null for call ${instantiationExecutableCall.executable} in model $assembleModel" diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/OptionalConstructors.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/OptionalConstructors.kt index 7f82d9dad8..ae3b062c47 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/OptionalConstructors.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/OptionalConstructors.kt @@ -4,7 +4,6 @@ import org.utbot.framework.plugin.api.ClassId import org.utbot.framework.plugin.api.MethodId import org.utbot.framework.plugin.api.UtAssembleModel import org.utbot.framework.plugin.api.UtExecutableCallModel -import org.utbot.framework.plugin.api.UtStatementModel import org.utbot.framework.plugin.api.util.doubleClassId import org.utbot.framework.plugin.api.util.id import org.utbot.framework.plugin.api.util.intClassId @@ -24,21 +23,16 @@ internal sealed class OptionalConstructorBase : UtAssembleModelConstructorBase() abstract val isPresent: KFunction1<*, Boolean> abstract val getter: KFunction1<*, Any> - - private val emptyMethodId by lazy { MethodId(classId, "empty", classId, emptyList()) } - private val ofMethodId by lazy { MethodId(classId, "of", classId, listOf(elementClassId)) } - - final override fun UtAssembleModel.modifyChains( + final override fun provideInstantiationCall( internalConstructor: UtModelConstructorInterface, - instantiationChain: MutableList, - modificationChain: MutableList, - valueToConstructFrom: Any - ) { - require(classId.jClass.isInstance(valueToConstructFrom)) { - "Can't cast $valueToConstructFrom to ${classId.jClass} in $this assemble constructor." + value: Any, + classId: ClassId + ): UtExecutableCallModel { + require(classId.jClass.isInstance(value)) { + "Can't cast $value to ${classId.jClass} in $this assemble constructor." } - instantiationChain += if (!isPresent.call(valueToConstructFrom)) { + return if (!isPresent.call(value)) { UtExecutableCallModel( instance = null, emptyMethodId, @@ -48,10 +42,18 @@ internal sealed class OptionalConstructorBase : UtAssembleModelConstructorBase() UtExecutableCallModel( instance = null, ofMethodId, - listOf(internalConstructor.construct(getter.call(valueToConstructFrom), elementClassId)) + listOf(internalConstructor.construct(getter.call(value), elementClassId)) ) } } + + private val emptyMethodId by lazy { MethodId(classId, "empty", classId, emptyList()) } + private val ofMethodId by lazy { MethodId(classId, "of", classId, listOf(elementClassId)) } + + final override fun UtAssembleModel.provideModificationChain( + internalConstructor: UtModelConstructorInterface, + value: Any + ): List = emptyList() } internal class OptionalConstructor : OptionalConstructorBase() { diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/PrimitiveWrapperConstructor.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/PrimitiveWrapperConstructor.kt index 29680feb24..8b57561ff1 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/PrimitiveWrapperConstructor.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/PrimitiveWrapperConstructor.kt @@ -11,20 +11,25 @@ import org.utbot.framework.plugin.api.util.primitiveByWrapper import org.utbot.framework.plugin.api.util.stringClassId internal class PrimitiveWrapperConstructor : UtAssembleModelConstructorBase() { - override fun UtAssembleModel.modifyChains( + override fun provideInstantiationCall( internalConstructor: UtModelConstructorInterface, - instantiationChain: MutableList, - modificationChain: MutableList, - valueToConstructFrom: Any - ) { - checkClassCast(classId.jClass, valueToConstructFrom::class.java) + value: Any, + classId: ClassId + ): UtExecutableCallModel { + checkClassCast(classId.jClass, value::class.java) - instantiationChain += UtExecutableCallModel( + return UtExecutableCallModel( null, constructorId(classId, classId.unbox()), - listOf(UtPrimitiveModel(valueToConstructFrom)) + listOf(UtPrimitiveModel(value)) ) + } + + override fun UtAssembleModel.provideModificationChain( + internalConstructor: UtModelConstructorInterface, + value: Any + ): List = emptyList() } diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/UtAssembleModelConstructors.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/UtAssembleModelConstructors.kt index 33cc6bf4fb..e870870492 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/UtAssembleModelConstructors.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/UtAssembleModelConstructors.kt @@ -2,6 +2,7 @@ package org.utbot.framework.concrete import org.utbot.framework.plugin.api.ClassId import org.utbot.framework.plugin.api.UtAssembleModel +import org.utbot.framework.plugin.api.UtExecutableCallModel import org.utbot.framework.plugin.api.UtStatementModel import org.utbot.framework.plugin.api.util.jClass import org.utbot.framework.plugin.api.util.primitiveWrappers @@ -92,25 +93,29 @@ internal fun findUtAssembleModelConstructor(classId: ClassId): UtAssembleModelCo internal abstract class UtAssembleModelConstructorBase { fun constructAssembleModel( internalConstructor: UtModelConstructorInterface, - valueToConstructFrom: Any, + value: Any, valueClassId: ClassId, id: Int?, init: (UtAssembleModel) -> Unit ): UtAssembleModel { - val instantiationChain = mutableListOf() - val modificationChain = mutableListOf() val baseName = valueClassId.simpleName.decapitalize() - return UtAssembleModel(id, valueClassId, nextModelName(baseName), instantiationChain, modificationChain) - .also(init) - .apply { modifyChains(internalConstructor, instantiationChain, modificationChain, valueToConstructFrom) } + val instantiationCall = provideInstantiationCall(internalConstructor, value, valueClassId) + return UtAssembleModel(id, valueClassId, nextModelName(baseName), instantiationCall) { + init(this) + provideModificationChain(internalConstructor, value) + } } - protected abstract fun UtAssembleModel.modifyChains( + protected abstract fun provideInstantiationCall( internalConstructor: UtModelConstructorInterface, - instantiationChain: MutableList, - modificationChain: MutableList, - valueToConstructFrom: Any - ) + value: Any, + classId: ClassId + ): UtExecutableCallModel + + protected abstract fun UtAssembleModel.provideModificationChain( + internalConstructor: UtModelConstructorInterface, + value: Any + ): List } internal fun UtAssembleModelConstructorBase.checkClassCast(expected: Class<*>, actual: Class<*>) { diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/minimization/Minimization.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/minimization/Minimization.kt index c6b336098a..3a054916b3 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/minimization/Minimization.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/minimization/Minimization.kt @@ -222,7 +222,9 @@ private fun UtModel.calculateSize(used: MutableSet = mutableSetOf()): I return when (this) { is UtNullModel, is UtPrimitiveModel, UtVoidModel -> 0 is UtClassRefModel, is UtEnumConstantModel, is UtArrayModel -> 1 - is UtAssembleModel -> 1 + allStatementsChain.sumOf { it.calculateSize(used) } + is UtAssembleModel -> { + 1 + instantiationCall.calculateSize(used) + modificationsChain.sumOf { it.calculateSize(used) } + } is UtCompositeModel -> 1 + fields.values.sumOf { it.calculateSize(used) } is UtLambdaModel -> 1 + capturedValues.sumOf { it.calculateSize(used) } } diff --git a/utbot-framework/src/main/kotlin/org/utbot/fuzzer/FallbackModelProvider.kt b/utbot-framework/src/main/kotlin/org/utbot/fuzzer/FallbackModelProvider.kt index ad23b7bf43..acd4c14420 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/fuzzer/FallbackModelProvider.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/fuzzer/FallbackModelProvider.kt @@ -94,17 +94,12 @@ open class FallbackModelProvider( UtNullModel(kclass.java.id) } defaultConstructor != null -> { - val chain = mutableListOf() - val model = UtAssembleModel( + UtAssembleModel( id = idGenerator.createId(), kclass.id, kclass.id.toString(), - chain + UtExecutableCallModel(null, defaultConstructor.executableId, listOf()) ) - chain.add( - UtExecutableCallModel(model, defaultConstructor.executableId, listOf()) - ) - model } else -> { UtCompositeModel( diff --git a/utbot-framework/src/main/kotlin/org/utbot/tests/infrastructure/UtModelTestCaseChecker.kt b/utbot-framework/src/main/kotlin/org/utbot/tests/infrastructure/UtModelTestCaseChecker.kt index a33b5b980b..fb4399d81a 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/tests/infrastructure/UtModelTestCaseChecker.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/tests/infrastructure/UtModelTestCaseChecker.kt @@ -186,7 +186,7 @@ abstract class UtModelTestCaseChecker( protected fun UtModel.findField(fieldId: FieldId): UtModel = when (this) { is UtCompositeModel -> this.fields[fieldId]!! is UtAssembleModel -> { - val fieldAccess = this.allStatementsChain + val fieldAccess = this.modificationsChain .filterIsInstance() .singleOrNull { it.fieldId == fieldId } fieldAccess?.fieldModel ?: fieldId.type.defaultValueModel() diff --git a/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/objects/AssembleModelUtils.kt b/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/objects/AssembleModelUtils.kt index 1e022c82c9..202ed0f73b 100644 --- a/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/objects/AssembleModelUtils.kt +++ b/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/objects/AssembleModelUtils.kt @@ -10,16 +10,13 @@ import org.utbot.fuzzer.hex fun ModelProvider.assembleModel(id: Int, constructorId: ConstructorId, params: List): FuzzedValue { - val instantiationChain = mutableListOf() + mutableListOf() return UtAssembleModel( id, constructorId.classId, "${constructorId.classId.name}${constructorId.parameters}#" + id.hex(), - instantiationChain = instantiationChain, - modificationsChain = mutableListOf() - ).apply { - instantiationChain += UtExecutableCallModel(null, constructorId, params.map { it.model }) - }.fuzzed { + UtExecutableCallModel(null, constructorId, params.map { it.model }) + ).fuzzed { summary = "%var% = ${constructorId.classId.simpleName}(${constructorId.parameters.joinToString { it.simpleName }})" } } diff --git a/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/providers/CollectionModelProvider.kt b/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/providers/CollectionModelProvider.kt index 0a9c242e05..533a0ab14d 100644 --- a/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/providers/CollectionModelProvider.kt +++ b/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/providers/CollectionModelProvider.kt @@ -92,15 +92,13 @@ class CollectionModelProvider( private fun Class<*>.methodCall(methodName: String, returnType: Class<*>, params: List> = emptyList()) = MethodId(id, methodName, returnType.id, params.map { it.id }) private fun Class<*>.createdBy(init: ExecutableId, params: List = emptyList()): UtAssembleModel { - val instantiationChain = mutableListOf() + val instantiationCall = UtExecutableCallModel(null, init, params) val genId = idGenerator.createId() return UtAssembleModel( genId, id, "${init.classId.name}${init.parameters}#" + genId.toString(16), - instantiationChain - ).apply { - instantiationChain += UtExecutableCallModel(null, init, params) - } + instantiationCall + ) } } \ No newline at end of file diff --git a/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/providers/DateConstantModelProvider.kt b/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/providers/DateConstantModelProvider.kt index 1b33e977d1..82ab91ad14 100644 --- a/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/providers/DateConstantModelProvider.kt +++ b/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/providers/DateConstantModelProvider.kt @@ -135,17 +135,15 @@ class DateConstantModelProvider( val simpleDateFormatModel = assembleSimpleDateFormat(idGenerator.createId(), formatString) val dateFormatParse = simpleDateFormatModel.classId.jClass .getMethod("parse", String::class.java).executableId - val instantiationChain = mutableListOf() + val instantiationCall = UtExecutableCallModel( + simpleDateFormatModel, dateFormatParse, listOf(UtPrimitiveModel(dateString)) + ) return UtAssembleModel( id, dateClassId, "$dateFormatParse#" + id.hex(), - instantiationChain - ).apply { - instantiationChain += UtExecutableCallModel( - simpleDateFormatModel, dateFormatParse, listOf(UtPrimitiveModel(dateString)) - ) - }.fuzzed { + instantiationCall + ).fuzzed { summary = "%var% = $dateFormatParse($stringClassId)" } } @@ -158,21 +156,14 @@ class DateConstantModelProvider( val formatSetLenient = SimpleDateFormat::setLenient.executableId val formatModel = UtPrimitiveModel(formatString) - val instantiationChain = mutableListOf() - val modificationsChain = mutableListOf() + val instantiationCall = UtExecutableCallModel(instance = null, formatStringConstructor, listOf(formatModel)) return UtAssembleModel( id, simpleDateFormatId, "$simpleDateFormatId[$stringClassId]#" + id.hex(), - instantiationChain, - modificationsChain + instantiationCall ).apply { - instantiationChain += UtExecutableCallModel( - instance = null, formatStringConstructor, listOf(formatModel) - ) - modificationsChain += UtExecutableCallModel( - instance = this, formatSetLenient, listOf(UtPrimitiveModel(false)) - ) + listOf(UtExecutableCallModel(instance = this, formatSetLenient, listOf(UtPrimitiveModel(false)))) } } From 42c66ae426f87a96f87fb1782640bb965859c7e4 Mon Sep 17 00:00:00 2001 From: Sergey Pospelov Date: Mon, 19 Sep 2022 18:08:07 +0300 Subject: [PATCH 4/9] Fix: turn on test --- .../deepequals/ClassWithCrossReferenceRelationshipTest.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/utbot-framework-test/src/test/kotlin/org/utbot/examples/codegen/deepequals/ClassWithCrossReferenceRelationshipTest.kt b/utbot-framework-test/src/test/kotlin/org/utbot/examples/codegen/deepequals/ClassWithCrossReferenceRelationshipTest.kt index 5fd79a17e7..c857384e0a 100644 --- a/utbot-framework-test/src/test/kotlin/org/utbot/examples/codegen/deepequals/ClassWithCrossReferenceRelationshipTest.kt +++ b/utbot-framework-test/src/test/kotlin/org/utbot/examples/codegen/deepequals/ClassWithCrossReferenceRelationshipTest.kt @@ -16,8 +16,6 @@ class ClassWithCrossReferenceRelationshipTest : UtValueTestCaseChecker( CodeGenerationLanguageLastStage(CodegenLanguage.KOTLIN, CodeGeneration) ) ) { - // TODO: The test is disabled due to [https://github.com/UnitTestBot/UTBotJava/issues/812] - @Disabled @Test fun testClassWithCrossReferenceRelationship() { check( From b190d701383fff4c33a678a55ae774cb8a06564a Mon Sep 17 00:00:00 2001 From: Sergey Pospelov Date: Mon, 19 Sep 2022 18:11:26 +0300 Subject: [PATCH 5/9] Add: a small comment on `UtExecutableCallModel` --- .../src/main/kotlin/org/utbot/framework/plugin/api/Api.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/Api.kt b/utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/Api.kt index f04983fb5e..9720c3f942 100644 --- a/utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/Api.kt +++ b/utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/Api.kt @@ -588,6 +588,8 @@ sealed class UtStatementModel( * Step of assemble instruction that calls executable. * * Contains executable to call, call parameters and an instance model before call. + * + * @param [instance] **must be** `null` for static methods and constructors */ data class UtExecutableCallModel( override val instance: UtReferenceModel?, From 47c498fcc520406f4def11019c62ad807dc3d693 Mon Sep 17 00:00:00 2001 From: Sergey Pospelov Date: Mon, 19 Sep 2022 18:33:33 +0300 Subject: [PATCH 6/9] Fix: `DateConstantModelProvider` --- .../org/utbot/fuzzer/providers/DateConstantModelProvider.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/providers/DateConstantModelProvider.kt b/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/providers/DateConstantModelProvider.kt index 82ab91ad14..f425937fca 100644 --- a/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/providers/DateConstantModelProvider.kt +++ b/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/providers/DateConstantModelProvider.kt @@ -162,7 +162,7 @@ class DateConstantModelProvider( simpleDateFormatId, "$simpleDateFormatId[$stringClassId]#" + id.hex(), instantiationCall - ).apply { + ) { listOf(UtExecutableCallModel(instance = this, formatSetLenient, listOf(UtPrimitiveModel(false)))) } } From 8d69f66790118e1c89166842bece7629e3542f64 Mon Sep 17 00:00:00 2001 From: Sergey Pospelov Date: Mon, 19 Sep 2022 19:37:48 +0300 Subject: [PATCH 7/9] Fix: review comments --- .../src/main/kotlin/org/utbot/framework/plugin/api/Api.kt | 2 +- .../deepequals/ClassWithCrossReferenceRelationshipTest.kt | 5 ++--- .../src/main/kotlin/org/utbot/engine/ObjectWrappers.kt | 4 ++-- .../src/main/kotlin/org/utbot/engine/OptionalWrapper.kt | 6 ++++-- .../src/main/kotlin/org/utbot/engine/Resolver.kt | 2 +- .../main/kotlin/org/utbot/engine/SecurityManagerWrapper.kt | 2 +- utbot-framework/src/main/kotlin/org/utbot/engine/Strings.kt | 4 ++-- .../org/utbot/framework/assemble/AssembleModelGenerator.kt | 4 ++-- .../codegen/model/constructor/tree/CgVariableConstructor.kt | 4 ++-- .../org/utbot/framework/concrete/IterableConstructors.kt | 2 +- .../utbot/framework/concrete/PrimitiveWrapperConstructor.kt | 2 +- .../main/kotlin/org/utbot/fuzzer/FallbackModelProvider.kt | 2 +- .../kotlin/org/utbot/fuzzer/objects/AssembleModelUtils.kt | 2 +- .../org/utbot/fuzzer/providers/CollectionModelProvider.kt | 2 +- 14 files changed, 22 insertions(+), 21 deletions(-) diff --git a/utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/Api.kt b/utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/Api.kt index 9720c3f942..3401ba0f0c 100644 --- a/utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/Api.kt +++ b/utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/Api.kt @@ -473,7 +473,7 @@ data class UtArrayModel( * * The default constructor is made private to enforce using a safe constructor. * - * @param instantiationCall is an [UtExecutableCallModel] to instantiate represented object. + * @param instantiationCall is an [UtExecutableCallModel] to instantiate represented object. It **must** not return `null`. * @param modificationsChain is a chain of [UtStatementModel] to construct object state. */ data class UtAssembleModel private constructor( diff --git a/utbot-framework-test/src/test/kotlin/org/utbot/examples/codegen/deepequals/ClassWithCrossReferenceRelationshipTest.kt b/utbot-framework-test/src/test/kotlin/org/utbot/examples/codegen/deepequals/ClassWithCrossReferenceRelationshipTest.kt index c857384e0a..3d62c2acb2 100644 --- a/utbot-framework-test/src/test/kotlin/org/utbot/examples/codegen/deepequals/ClassWithCrossReferenceRelationshipTest.kt +++ b/utbot-framework-test/src/test/kotlin/org/utbot/examples/codegen/deepequals/ClassWithCrossReferenceRelationshipTest.kt @@ -1,12 +1,11 @@ package org.utbot.examples.codegen.deepequals -import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test -import org.utbot.tests.infrastructure.DoNotCalculate -import org.utbot.tests.infrastructure.UtValueTestCaseChecker import org.utbot.framework.plugin.api.CodegenLanguage import org.utbot.testcheckers.eq import org.utbot.tests.infrastructure.CodeGeneration +import org.utbot.tests.infrastructure.DoNotCalculate +import org.utbot.tests.infrastructure.UtValueTestCaseChecker class ClassWithCrossReferenceRelationshipTest : UtValueTestCaseChecker( testClass = ClassWithCrossReferenceRelationship::class, diff --git a/utbot-framework/src/main/kotlin/org/utbot/engine/ObjectWrappers.kt b/utbot-framework/src/main/kotlin/org/utbot/engine/ObjectWrappers.kt index 1ea60aa140..87e7470496 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/engine/ObjectWrappers.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/engine/ObjectWrappers.kt @@ -242,9 +242,9 @@ data class ThrowableWrapper(val throwable: Throwable) : WrapperInterface { val modelName = nextModelName(throwable.javaClass.simpleName.decapitalize()) val instantiationCall = when (val message = throwable.message) { - null -> UtExecutableCallModel(null, constructorId(classId), emptyList()) + null -> UtExecutableCallModel(instance = null, constructorId(classId), emptyList()) else -> UtExecutableCallModel( - null, + instance = null, constructorId(classId, stringClassId), listOf(UtPrimitiveModel(message)) ) diff --git a/utbot-framework/src/main/kotlin/org/utbot/engine/OptionalWrapper.kt b/utbot-framework/src/main/kotlin/org/utbot/engine/OptionalWrapper.kt index 7ce2226d14..7fc3930ba5 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/engine/OptionalWrapper.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/engine/OptionalWrapper.kt @@ -106,7 +106,8 @@ class OptionalWrapper(private val utOptionalClass: UtOptionalClass) : BaseOverri } return if (!isPresent) { UtExecutableCallModel( - null, MethodId( + instance = null, + MethodId( classId, "empty", classId, @@ -115,7 +116,8 @@ class OptionalWrapper(private val utOptionalClass: UtOptionalClass) : BaseOverri ) } else { UtExecutableCallModel( - null, MethodId( + instance = null, + MethodId( classId, "of", classId, diff --git a/utbot-framework/src/main/kotlin/org/utbot/engine/Resolver.kt b/utbot-framework/src/main/kotlin/org/utbot/engine/Resolver.kt index 3b1cc4bbb8..ec4dcd7a9b 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/engine/Resolver.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/engine/Resolver.kt @@ -550,7 +550,7 @@ class Resolver( val baseModelName = primitiveClassId.name val constructorId = constructorId(classId, primitiveClassId) val valueModel = fields[FieldId(classId, "value")] ?: primitiveClassId.defaultValueModel() - val instantiationCall = UtExecutableCallModel(null, constructorId, listOf(valueModel)) + val instantiationCall = UtExecutableCallModel(instance = null, constructorId, listOf(valueModel)) UtAssembleModel(addr, classId, nextModelName(baseModelName), instantiationCall) } } diff --git a/utbot-framework/src/main/kotlin/org/utbot/engine/SecurityManagerWrapper.kt b/utbot-framework/src/main/kotlin/org/utbot/engine/SecurityManagerWrapper.kt index ec686b32aa..33f8511dfa 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/engine/SecurityManagerWrapper.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/engine/SecurityManagerWrapper.kt @@ -29,7 +29,7 @@ class SecurityManagerWrapper : BaseOverriddenWrapper(utSecurityManagerClass.name val modelName = nextModelName(baseModelName) val instantiationCall = UtExecutableCallModel( - null, + instance = null, System::getSecurityManager.executableId, emptyList() ) diff --git a/utbot-framework/src/main/kotlin/org/utbot/engine/Strings.kt b/utbot-framework/src/main/kotlin/org/utbot/engine/Strings.kt index ea19138160..08a6083c36 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/engine/Strings.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/engine/Strings.kt @@ -329,12 +329,12 @@ sealed class UtAbstractStringBuilderWrapper(className: String) : BaseOverriddenW val charValues = CharArray(length) { (values.stores[it] as UtPrimitiveModel).value as Char } val stringModel = UtPrimitiveModel(String(charValues)) val constructorId = constructorId(wrapper.type.classId, STRING_TYPE.classId) - val instantiationChain = UtExecutableCallModel( + val instantiationCall = UtExecutableCallModel( instance = null, constructorId, listOf(stringModel) ) - return UtAssembleModel(addr, wrapper.type.classId, modelName, instantiationChain) + return UtAssembleModel(addr, wrapper.type.classId, modelName, instantiationCall) } private val SootClass.valueField: SootField diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/assemble/AssembleModelGenerator.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/assemble/AssembleModelGenerator.kt index 5cb26ff8b3..edd8b669d1 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/assemble/AssembleModelGenerator.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/assemble/AssembleModelGenerator.kt @@ -291,7 +291,7 @@ class AssembleModelGenerator(private val methodPackageName: String) { modelBefore.modelName, assembleExecutableCallModel(modelBefore.instantiationCall), modelBefore.origin - ).apply { + ) { instantiatedModels[modelBefore] = this modelBefore.modificationsChain.map { assembleStatementModel(it) } } @@ -361,7 +361,7 @@ class AssembleModelGenerator(private val methodPackageName: String) { assembleModel(fieldModel) } - return UtExecutableCallModel(null, constructorInfo.constructorId, constructorParams) + return UtExecutableCallModel(instance = null, constructorInfo.constructorId, constructorParams) } /** diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/tree/CgVariableConstructor.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/tree/CgVariableConstructor.kt index 5f58d67a1d..09f54b703b 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/tree/CgVariableConstructor.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/tree/CgVariableConstructor.kt @@ -201,8 +201,8 @@ internal class CgVariableConstructor(val context: CgContext) : } private fun constructAssemble(model: UtAssembleModel, baseName: String?): CgValue { - val instantiationExecutableCall = model.instantiationCall - processInstantiationStatement(model, instantiationExecutableCall, baseName) + val instantiationCall = model.instantiationCall + processInstantiationStatement(model, instantiationCall, baseName) for (statementModel in model.modificationsChain) { when (statementModel) { diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/IterableConstructors.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/IterableConstructors.kt index 2cb45038dd..6866000d06 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/IterableConstructors.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/IterableConstructors.kt @@ -19,7 +19,7 @@ internal class CollectionConstructor : UtAssembleModelConstructorBase() { @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN") value as java.util.Collection<*> - // If [valueToConstructFrom] constructed incorrectly (some inner transient fields are null, etc.) this may fail. + // If [value] constructed incorrectly (some inner transient fields are null, etc.) this may fail. // This value will be constructed as UtCompositeModel. val models = value.map { internalConstructor.construct(it, valueToClassId(it)) } diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/PrimitiveWrapperConstructor.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/PrimitiveWrapperConstructor.kt index 8b57561ff1..d9521caf3f 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/PrimitiveWrapperConstructor.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/concrete/PrimitiveWrapperConstructor.kt @@ -19,7 +19,7 @@ internal class PrimitiveWrapperConstructor : UtAssembleModelConstructorBase() { checkClassCast(classId.jClass, value::class.java) return UtExecutableCallModel( - null, + instance = null, constructorId(classId, classId.unbox()), listOf(UtPrimitiveModel(value)) ) diff --git a/utbot-framework/src/main/kotlin/org/utbot/fuzzer/FallbackModelProvider.kt b/utbot-framework/src/main/kotlin/org/utbot/fuzzer/FallbackModelProvider.kt index acd4c14420..9ca0140c57 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/fuzzer/FallbackModelProvider.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/fuzzer/FallbackModelProvider.kt @@ -98,7 +98,7 @@ open class FallbackModelProvider( id = idGenerator.createId(), kclass.id, kclass.id.toString(), - UtExecutableCallModel(null, defaultConstructor.executableId, listOf()) + UtExecutableCallModel(instance = null, defaultConstructor.executableId, listOf()) ) } else -> { diff --git a/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/objects/AssembleModelUtils.kt b/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/objects/AssembleModelUtils.kt index 202ed0f73b..3a653a6086 100644 --- a/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/objects/AssembleModelUtils.kt +++ b/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/objects/AssembleModelUtils.kt @@ -15,7 +15,7 @@ fun ModelProvider.assembleModel(id: Int, constructorId: ConstructorId, params: L id, constructorId.classId, "${constructorId.classId.name}${constructorId.parameters}#" + id.hex(), - UtExecutableCallModel(null, constructorId, params.map { it.model }) + UtExecutableCallModel(instance = null, constructorId, params.map { it.model }) ).fuzzed { summary = "%var% = ${constructorId.classId.simpleName}(${constructorId.parameters.joinToString { it.simpleName }})" } diff --git a/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/providers/CollectionModelProvider.kt b/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/providers/CollectionModelProvider.kt index 533a0ab14d..41d81ea448 100644 --- a/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/providers/CollectionModelProvider.kt +++ b/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/providers/CollectionModelProvider.kt @@ -92,7 +92,7 @@ class CollectionModelProvider( private fun Class<*>.methodCall(methodName: String, returnType: Class<*>, params: List> = emptyList()) = MethodId(id, methodName, returnType.id, params.map { it.id }) private fun Class<*>.createdBy(init: ExecutableId, params: List = emptyList()): UtAssembleModel { - val instantiationCall = UtExecutableCallModel(null, init, params) + val instantiationCall = UtExecutableCallModel(instance = null, init, params) val genId = idGenerator.createId() return UtAssembleModel( genId, From f64a91db02ad3e1034182d43e4d69193b2379c99 Mon Sep 17 00:00:00 2001 From: Sergey Pospelov Date: Mon, 19 Sep 2022 22:31:09 +0300 Subject: [PATCH 8/9] Fix: failing tests --- .../assemble/AssembleModelGeneratorTests.kt | 20 +++++++------- .../framework/plugin/api/ModelProviderTest.kt | 27 ++++++++----------- 2 files changed, 21 insertions(+), 26 deletions(-) diff --git a/utbot-framework-test/src/test/kotlin/org/utbot/framework/assemble/AssembleModelGeneratorTests.kt b/utbot-framework-test/src/test/kotlin/org/utbot/framework/assemble/AssembleModelGeneratorTests.kt index 0108faad44..278cfac453 100644 --- a/utbot-framework-test/src/test/kotlin/org/utbot/framework/assemble/AssembleModelGeneratorTests.kt +++ b/utbot-framework-test/src/test/kotlin/org/utbot/framework/assemble/AssembleModelGeneratorTests.kt @@ -184,7 +184,7 @@ class AssembleModelGeneratorTests { val firstExpectedRepresentation = printExpectedModel(testClassId.simpleName, v1, statementsChain.toList()) statementsChain.clear() - statementsChain.add("val $v2 = ${innerClassId.canonicalName}()") + statementsChain.add("${innerClassId.canonicalName}()") statementsChain.add("$v2." + addExpectedSetter("a", 2)) statementsChain.add("$v2." + ("b" `=` 4)) val secondExpectedRepresentation = printExpectedModel(innerClassId.simpleName, v2, statementsChain.toList()) @@ -238,7 +238,7 @@ class AssembleModelGeneratorTests { val firstExpectedRepresentation = printExpectedModel(listClassId.simpleName, v1, statementsChain.toList()) statementsChain.clear() - statementsChain.add("val $v2 = ${listClassId.canonicalName}()") + statementsChain.add("${listClassId.canonicalName}()") statementsChain.add("$v2." + addExpectedSetter("value", 2)) val secondExpectedRepresentation = printExpectedModel(listClassId.simpleName, v2, statementsChain.toList()) @@ -268,13 +268,13 @@ class AssembleModelGeneratorTests { val firstExpectedRepresentation = printExpectedModel(listClassId.simpleName, v1, statementsChain.toList()) statementsChain.clear() - statementsChain.add("val $v2 = ${listClassId.canonicalName}()") + statementsChain.add("${listClassId.canonicalName}()") statementsChain.add("$v2." + addExpectedSetter("value", 2)) statementsChain.add("$v2." + addExpectedSetter("next", v3)) val secondExpectedRepresentation = printExpectedModel(listClassId.simpleName, v2, statementsChain.toList()) statementsChain.clear() - statementsChain.add("val $v3 = ${listClassId.canonicalName}()") + statementsChain.add("${listClassId.canonicalName}()") statementsChain.add("$v3." + addExpectedSetter("value", 3)) statementsChain.add("$v3." + addExpectedSetter("next", v1)) val thirdExpectedRepresentation = printExpectedModel(listClassId.simpleName, v3, statementsChain.toList()) @@ -989,7 +989,7 @@ class AssembleModelGeneratorTests { val firstExpectedRepresentation = printExpectedModel(listClassId.simpleName, v1, statementsChain.toList()) statementsChain.clear() - statementsChain.add("val $v2 = ${listClassId.canonicalName}()") + statementsChain.add("${listClassId.canonicalName}()") statementsChain.add("$v2." + addExpectedSetter("value", 2)) val secondExpectedRepresentation = printExpectedModel(listClassId.simpleName, v2, statementsChain.toList()) @@ -1017,7 +1017,7 @@ class AssembleModelGeneratorTests { val firstExpectedRepresentation = printExpectedModel(listClassId.simpleName, v1, statementsChain.toList()) statementsChain.clear() - statementsChain.add("val $v2 = ${listClassId.canonicalName}()") + statementsChain.add("${listClassId.canonicalName}()") statementsChain.add("$v2." + addExpectedSetter("value", 2)) statementsChain.add("$v2." + addExpectedSetter("next", v1)) val secondExpectedRepresentation = printExpectedModel(listClassId.simpleName, v2, statementsChain) @@ -1140,7 +1140,7 @@ class AssembleModelGeneratorTests { statementsChain.add( "$v1." + ("array" `=` "[" + "null, " + - "UtAssembleModel(${innerClassId.simpleName} $v2) val $v2 = ${innerClassId.canonicalName}() $v2.setA(5), " + + "UtAssembleModel(${innerClassId.simpleName} $v2) ${innerClassId.canonicalName}() $v2.setA(5), " + "null" + "]") ) @@ -1240,8 +1240,8 @@ class AssembleModelGeneratorTests { val v3 = createExpectedVariableName() statementsChain.add( "$v1." + ("array" `=` "[" + - "[UtAssembleModel(${innerClassId.simpleName} $v2) val $v2 = ${innerClassId.canonicalName}() $v2.setA(5), ${null}], " + - "[UtAssembleModel(${innerClassId.simpleName} $v3) val $v3 = ${innerClassId.canonicalName}() $v3.b = 4, ${null}]" + + "[UtAssembleModel(${innerClassId.simpleName} $v2) ${innerClassId.canonicalName}() $v2.setA(5), ${null}], " + + "[UtAssembleModel(${innerClassId.simpleName} $v3) ${innerClassId.canonicalName}() $v3.b = 4, ${null}]" + "]") ) @@ -1480,7 +1480,7 @@ class AssembleModelGeneratorTests { val varName = createExpectedVariableName() val paramString = if (params.any()) params.joinToString(", ") else "" - this.add("val $varName = $fqn($paramString)") + this.add("$fqn($paramString)") return varName } diff --git a/utbot-fuzzers/src/test/kotlin/org/utbot/framework/plugin/api/ModelProviderTest.kt b/utbot-fuzzers/src/test/kotlin/org/utbot/framework/plugin/api/ModelProviderTest.kt index 4671e7a0a9..909741c55d 100644 --- a/utbot-fuzzers/src/test/kotlin/org/utbot/framework/plugin/api/ModelProviderTest.kt +++ b/utbot-fuzzers/src/test/kotlin/org/utbot/framework/plugin/api/ModelProviderTest.kt @@ -206,8 +206,7 @@ class ModelProviderTest { assertTrue(models[0]!!.all { it is UtAssembleModel && it.classId == classId }) models[0]!!.filterIsInstance().forEachIndexed { index, model -> - assertEquals(1, model.instantiationStatement.size) - val stm = model.instantiationStatement[0] + val stm = model.instantiationCall val paramCountInConstructorAsTheyListed = index + 1 assertEquals(paramCountInConstructorAsTheyListed, stm.params.size) } @@ -247,9 +246,8 @@ class ModelProviderTest { assertEquals(1, models.size) assertTrue(models[0]!!.isNotEmpty()) - val chain = (models[0]!![0] as UtAssembleModel).instantiationStatement - assertEquals(1, chain.size) - chain[0].params.forEach { + val chain = (models[0]!![0] as UtAssembleModel).instantiationCall + chain.params.forEach { assertEquals(intClassId, it.classId) } } @@ -366,14 +364,13 @@ class ModelProviderTest { assertEquals(1, result[0]!!.size) assertInstanceOf(UtAssembleModel::class.java, result[0]!![0]) assertEquals(A::class.java.id, result[0]!![0].classId) - (result[0]!![0] as UtAssembleModel).instantiationStatement.forEach { + (result[0]!![0] as UtAssembleModel).instantiationCall.let { assertEquals(1, it.params.size) val objectParamInConstructor = it.params[0] assertInstanceOf(UtAssembleModel::class.java, objectParamInConstructor) val innerAssembledModel = objectParamInConstructor as UtAssembleModel assertEquals(Any::class.java.id, innerAssembledModel.classId) - assertEquals(1, innerAssembledModel.instantiationStatement.size) - val objectCreation = innerAssembledModel.instantiationStatement.first() + val objectCreation = innerAssembledModel.instantiationCall assertEquals(0, objectCreation.params.size) assertInstanceOf(ConstructorId::class.java, objectCreation.executable) } @@ -395,13 +392,12 @@ class ModelProviderTest { assertEquals(1, result.size) assertEquals(1, result[0]!!.size) val outerModel = result[0]!![0] as UtAssembleModel - outerModel.instantiationStatement.forEach { + outerModel.instantiationCall.let { val constructorParameters = it.params assertEquals(1, constructorParameters.size) val innerModel = (constructorParameters[0] as UtAssembleModel) assertEquals(MyA::class.java.id, innerModel.classId) - assertEquals(1, innerModel.instantiationStatement.size) - val innerConstructorParameters = innerModel.instantiationStatement[0] + val innerConstructorParameters = innerModel.instantiationCall assertEquals(1, innerConstructorParameters.params.size) assertInstanceOf(UtNullModel::class.java, innerConstructorParameters.params[0]) } @@ -437,13 +433,12 @@ class ModelProviderTest { assertEquals(1, result.size) assertEquals(1, result[0]!!.size) val outerModel = result[0]!![0] as UtAssembleModel - outerModel.instantiationStatement.forEach { + outerModel.instantiationCall.let { val constructorParameters = it.params assertEquals(1, constructorParameters.size) val innerModel = (constructorParameters[0] as UtAssembleModel) assertEquals(Inner::class.java.id, innerModel.classId) - assertEquals(1, innerModel.instantiationStatement.size) - val innerConstructorParameters = innerModel.instantiationStatement[0] + val innerConstructorParameters = innerModel.instantiationCall assertEquals(2, innerConstructorParameters.params.size) assertTrue(innerConstructorParameters.params.all { param -> param is UtPrimitiveModel }) assertEquals(intClassId, innerConstructorParameters.params[0].classId) @@ -539,7 +534,7 @@ class ModelProviderTest { for (model in models) { val outerModel = (model as? UtAssembleModel) - ?.instantiationStatement as? UtExecutableCallModel + ?.instantiationCall ?: fail("No final instantiation model found for the outer class") for (param in outerModel.params) { when (param) { @@ -547,7 +542,7 @@ class ModelProviderTest { assertEquals(expectedIds[param.value], param.id) } is UtAssembleModel -> { - for (enumParam in (param.instantiationStatement as UtExecutableCallModel).params) { + for (enumParam in param.instantiationCall.params) { enumParam as UtEnumConstantModel assertEquals(expectedIds[enumParam.value], enumParam.id) } From e46d8485c62bfdac513c5fadcf60a213345efef0 Mon Sep 17 00:00:00 2001 From: Sergey Pospelov Date: Tue, 20 Sep 2022 09:40:42 +0300 Subject: [PATCH 9/9] Fix: review comments --- .../model/constructor/tree/CgVariableConstructor.kt | 13 ++++++++----- .../org/utbot/fuzzer/objects/AssembleModelUtils.kt | 1 - 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/tree/CgVariableConstructor.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/tree/CgVariableConstructor.kt index 09f54b703b..f8b453b55a 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/tree/CgVariableConstructor.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/constructor/tree/CgVariableConstructor.kt @@ -227,17 +227,20 @@ internal class CgVariableConstructor(val context: CgContext) : ) { val executable = executableCall.executable val params = executableCall.params - val cgCall = createCgExecutableCallFromUtExecutableCall(executableCall) val type = when (executable) { is MethodId -> executable.returnType is ConstructorId -> executable.classId } // Don't use redundant constructors for primitives and String - val initExpr = if (isPrimitiveWrapperOrString(type)) cgLiteralForWrapper(params) else cgCall - newVar(type, model, baseName) { initExpr } - .takeIf { executableCall == model.instantiationCall } - ?.also { valueByModelId[model.id] = it } + val initExpr = if (isPrimitiveWrapperOrString(type)) { + cgLiteralForWrapper(params) + } else { + createCgExecutableCallFromUtExecutableCall(executableCall) + } + newVar(type, model, baseName) { + initExpr + }.also { valueByModelId[model.id] = it } } diff --git a/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/objects/AssembleModelUtils.kt b/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/objects/AssembleModelUtils.kt index 3a653a6086..19947761bf 100644 --- a/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/objects/AssembleModelUtils.kt +++ b/utbot-fuzzers/src/main/kotlin/org/utbot/fuzzer/objects/AssembleModelUtils.kt @@ -10,7 +10,6 @@ import org.utbot.fuzzer.hex fun ModelProvider.assembleModel(id: Int, constructorId: ConstructorId, params: List): FuzzedValue { - mutableListOf() return UtAssembleModel( id, constructorId.classId,