Skip to content

Commit df9fec7

Browse files
committed
Review fixes
1 parent 88e6473 commit df9fec7

File tree

3 files changed

+41
-35
lines changed

3 files changed

+41
-35
lines changed

utbot-framework/src/main/kotlin/org/utbot/engine/ArrayObjectWrappers.kt

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -201,14 +201,8 @@ class RangeModifiableUnlimitedArrayWrapper : WrapperInterface {
201201
val addr = UtAddrExpression(value)
202202

203203
// Try to retrieve manually set type if present
204-
val valueTypeFromGenerics = typeRegistry.getTypeStoragesForObjectTypeParameters(wrapper.addr)
205-
206-
if (valueTypeFromGenerics != null && valueTypeFromGenerics.size > 1) {
207-
error("Range modifiable wrapper must have only one type parameter, but it got ${valueTypeFromGenerics.size}")
208-
}
209-
210-
val valueType = valueTypeFromGenerics
211-
?.single()
204+
val valueType = typeRegistry
205+
.extractSingleTypeParameterForRangeModifiableArray(wrapper.addr)
212206
?.leastCommonType
213207
?: OBJECT_TYPE
214208

@@ -347,15 +341,10 @@ class RangeModifiableUnlimitedArrayWrapper : WrapperInterface {
347341
// the constructed model to avoid infinite recursion below
348342
resolver.addConstructedModel(concreteAddr, resultModel)
349343

350-
val valueTypeStorageFromGenerics = resolver.typeRegistry.getTypeStoragesForObjectTypeParameters(wrapper.addr)
351-
352-
if (valueTypeStorageFromGenerics != null && valueTypeStorageFromGenerics.size > 1) {
353-
error("Range modifiable wrapper must have only one type parameter, but it got ${valueTypeStorageFromGenerics.size}")
354-
}
355-
356344
// try to retrieve type storage for the single type parameter
357-
val typeStorage = valueTypeStorageFromGenerics
358-
?.single()
345+
val typeStorage = resolver
346+
.typeRegistry
347+
.extractSingleTypeParameterForRangeModifiableArray(wrapper.addr)
359348
?: TypeRegistry.objectTypeStorage
360349

361350
(0 until sizeValue).associateWithTo(resultModel.stores) { i ->
@@ -373,6 +362,9 @@ class RangeModifiableUnlimitedArrayWrapper : WrapperInterface {
373362
return resultModel
374363
}
375364

365+
private fun TypeRegistry.extractSingleTypeParameterForRangeModifiableArray(addr: UtAddrExpression) =
366+
extractTypeStorageForObjectWithSingleTypeParameter(addr, "Range modifiable array")
367+
376368
companion object {
377369
internal val rangeModifiableArrayClass: SootClass
378370
get() = Scene.v().getSootClass(rangeModifiableArrayId.name)

utbot-framework/src/main/kotlin/org/utbot/engine/Traverser.kt

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,8 @@ import org.utbot.framework.plugin.api.FieldId
118118
import org.utbot.framework.plugin.api.MethodId
119119
import org.utbot.framework.plugin.api.classId
120120
import org.utbot.framework.plugin.api.id
121-
import org.utbot.framework.plugin.api.util.allDeclaredFieldIds
122121
import org.utbot.framework.plugin.api.util.executable
123-
import org.utbot.framework.plugin.api.util.fieldId
122+
import org.utbot.framework.plugin.api.util.findFieldByIdOrNull
124123
import org.utbot.framework.plugin.api.util.jField
125124
import org.utbot.framework.plugin.api.util.jClass
126125
import org.utbot.framework.plugin.api.util.id
@@ -2119,11 +2118,8 @@ class Traverser(
21192118

21202119
// We must have `runCatching` here since might be a situation when we do not have
21212120
// such declaring class in a classpath, that might (but should not) lead to an exception
2122-
val jClass = field.declaringClass.id.jClass
2123-
val requiredField = generateSequence(jClass) { it.superclass }
2124-
.flatMap { it.declaredFields.asSequence() }
2125-
.singleOrNull { it.name == field.name && it.declaringClass.name == field.declaringClass.name }
2126-
2121+
val classId = field.declaringClass.id
2122+
val requiredField = classId.findFieldByIdOrNull(field.fieldId)
21272123
val genericInfo = requiredField?.genericType as? ParameterizedType ?: return
21282124

21292125
updateGenericTypeInfo(genericInfo, createdField)
@@ -2552,10 +2548,14 @@ class Traverser(
25522548
): List<InvocationTarget> {
25532549
val visitor = solver.simplificator.axiomInstantiationVisitor
25542550
val simplifiedAddr = instance.addr.accept(visitor)
2551+
25552552
// UtIsExpression for object with address the same as instance.addr
2556-
val instanceOfConstraint = solver.assertions.singleOrNull {
2557-
it is UtIsExpression && it.addr == simplifiedAddr
2558-
} as? UtIsExpression
2553+
// If there are several such constraints, take the one with the least number of possible types
2554+
val instanceOfConstraint = solver.assertions
2555+
.filter { it is UtIsExpression && it.addr == simplifiedAddr }
2556+
.takeIf { it.isNotEmpty() }
2557+
?.minBy { (it as UtIsExpression).typeStorage.possibleConcreteTypes.size } as? UtIsExpression
2558+
25592559
// if we have UtIsExpression constraint for [instance], then find invocation targets
25602560
// for possibleTypes from this constraints, instead of the type maintained by solver.
25612561

@@ -2565,6 +2565,9 @@ class Traverser(
25652565
val types = instanceOfConstraint
25662566
?.typeStorage
25672567
?.possibleConcreteTypes
2568+
// we should take this constraint into consideration only if it has less
2569+
// possible types than our current object, otherwise, it doesn't add
2570+
// any helpful information
25682571
?.takeIf { it.size < instance.possibleConcreteTypes.size }
25692572
?: instance.possibleConcreteTypes
25702573

@@ -2703,21 +2706,14 @@ class Traverser(
27032706
// If we have some method 'foo` and a method `bar(List<Integer>), and inside `foo`
27042707
// there is an invocation `bar(object)`, this object must have information about
27052708
// its `Integer` generic type.
2706-
2707-
// Note that we must have `runCatching` here since might be a situation when we do not have
2708-
// such declaring class in a classpath, that might (but should not) lead to an exception
27092709
invocation.parameters.forEachIndexed { index, param ->
27102710
if (param !is ReferenceValue) return@forEachIndexed
27112711

2712-
runCatching {
2713-
updateGenericTypeInfoFromMethod(method, param, parameterIndex = index + 1)
2714-
}
2712+
updateGenericTypeInfoFromMethod(method, param, parameterIndex = index + 1)
27152713
}
27162714

27172715
if (invocation.instance != null) {
2718-
runCatching {
2719-
updateGenericTypeInfoFromMethod(method, invocation.instance, parameterIndex = 0)
2720-
}
2716+
updateGenericTypeInfoFromMethod(method, invocation.instance, parameterIndex = 0)
27212717
}
27222718

27232719
/**

utbot-framework/src/main/kotlin/org/utbot/engine/types/TypeRegistry.kt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,11 @@ class TypeRegistry {
503503
val updatedTypes = typeStorage.possibleConcreteTypes.intersect(newTypeStorage.possibleConcreteTypes)
504504

505505
// TODO should be really the least common type
506+
// we have two type storages and know that one of them is subset of another one.
507+
// Therefore, when we intersect them, we should chose correct least common type among them,
508+
// but we don't do it here since it is not obvious, what is a correct way to do it.
509+
// There is no access from here to typeResolver or Hierarchy, so it need to be
510+
// reconsidered in the future, how to intersect type storages here or extract this function.
506511
TypeStorage.constructTypeStorageUnsafe(typeStorage.leastCommonType, updatedTypes)
507512
}
508513

@@ -514,6 +519,19 @@ class TypeRegistry {
514519
*/
515520
fun getTypeStoragesForObjectTypeParameters(addr: UtAddrExpression): List<TypeStorage>? = genericTypeStorageByAddr[addr]
516521

522+
fun extractTypeStorageForObjectWithSingleTypeParameter(
523+
addr: UtAddrExpression,
524+
objectClassName: String
525+
): TypeStorage? {
526+
val valueTypeFromGenerics = getTypeStoragesForObjectTypeParameters(addr)
527+
528+
if (valueTypeFromGenerics != null && valueTypeFromGenerics.size > 1) {
529+
error("$objectClassName must have only one type parameter, but it got ${valueTypeFromGenerics.size}")
530+
}
531+
532+
return valueTypeFromGenerics?.single()
533+
}
534+
517535
/**
518536
* Set types storages for [firstAddr]'s type parameters equal to type storages for [secondAddr]'s type parameters
519537
* according to provided types injection represented by [indexInjection].

0 commit comments

Comments
 (0)