From de865a56cc4d7e02e2d995e81205e14e42e99fe0 Mon Sep 17 00:00:00 2001 From: Andrey Tarbeev Date: Wed, 7 Dec 2022 22:52:49 +0300 Subject: [PATCH] Fix unnecessary reflection calls and infinite loop in self-reference initializations --- .../framework/assemble/AssembleModelGenerator.kt | 13 ++++++++++++- .../framework/modifications/ConstructorAnalyzer.kt | 13 +++---------- 2 files changed, 15 insertions(+), 11 deletions(-) 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 ae9546fbfe..66fd1632f3 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 @@ -226,6 +226,8 @@ class AssembleModelGenerator(private val basePackageName: String) { assembleModel } + private val modelsInAnalysis = mutableListOf() + /** * Assembles internal structure of [UtCompositeModel] if possible and handles assembling exceptions. */ @@ -243,7 +245,14 @@ class AssembleModelGenerator(private val basePackageName: String) { val constructorId = findBestConstructorOrNull(compositeModel) ?: throw AssembleException("No default constructor to instantiate an object of the class ${compositeModel.classId}") - val constructorInfo = constructorAnalyzer.analyze(constructorId) + // we do not analyze a constructor which is currently in the analysis + // thus, we do not encounter an infinite loop in self or cross-reference situations + val shouldAnalyzeConstructor = compositeModel !in modelsInAnalysis + modelsInAnalysis.add(compositeModel) + + val constructorInfo = + if (shouldAnalyzeConstructor) constructorAnalyzer.analyze(constructorId) + else ConstructorAssembleInfo(constructorId) val instantiationCall = constructorCall(compositeModel, constructorInfo) return UtAssembleModel( @@ -284,6 +293,8 @@ class AssembleModelGenerator(private val basePackageName: String) { } catch (e: AssembleException) { instantiatedModels.remove(compositeModel) throw e + } finally { + modelsInAnalysis.remove(compositeModel) } } diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/modifications/ConstructorAnalyzer.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/modifications/ConstructorAnalyzer.kt index d022c03e33..09dbd41d4c 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/modifications/ConstructorAnalyzer.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/modifications/ConstructorAnalyzer.kt @@ -33,9 +33,9 @@ import soot.jimple.internal.JimpleLocal * */ data class ConstructorAssembleInfo( val constructorId: ConstructorId, - val params: Map, - val setFields: Set, - val affectedFields: Set + val params: Map = mapOf(), + val setFields: Set = setOf(), + val affectedFields: Set = setOf() ) /** @@ -109,18 +109,11 @@ class ConstructorAnalyzer { return jimpleLocal.name.first() != '$' } - private val visitedConstructors = mutableSetOf() - private fun analyze( sootConstructor: SootMethod, setFields: MutableSet, affectedFields: MutableSet, ): Map { - if (sootConstructor in visitedConstructors) { - return emptyMap() - } - visitedConstructors.add(sootConstructor) - val jimpleBody = retrieveJimpleBody(sootConstructor) ?: return emptyMap() analyzeAssignments(jimpleBody, setFields, affectedFields)