Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix wrapper concrete types #964

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package org.utbot.examples.casts

import org.utbot.tests.infrastructure.UtValueTestCaseChecker
import org.utbot.tests.infrastructure.DoNotCalculate
import org.utbot.tests.infrastructure.ignoreExecutionsNumber
import org.utbot.framework.plugin.api.CodegenLanguage
import org.junit.jupiter.api.Disabled
import org.junit.jupiter.api.Test
import org.utbot.framework.plugin.api.CodegenLanguage
import org.utbot.testcheckers.eq
import org.utbot.testcheckers.ge
import org.utbot.tests.infrastructure.CodeGeneration
import org.utbot.tests.infrastructure.DoNotCalculate
import org.utbot.tests.infrastructure.UtValueTestCaseChecker
import org.utbot.tests.infrastructure.ignoreExecutionsNumber

// TODO failed Kotlin compilation SAT-1332
internal class InstanceOfExampleTest : UtValueTestCaseChecker(
Expand Down Expand Up @@ -404,6 +404,65 @@ internal class InstanceOfExampleTest : UtValueTestCaseChecker(
)
}

@Test
SBOne-Kenobi marked this conversation as resolved.
Show resolved Hide resolved
fun testStringInstanceOf() {
check(
InstanceOfExample::charSequenceInstanceOf,
eq(2),
{ _, r -> r == null },
{ _, r -> r!!::class == String::class }
)
}

@Test
fun testListInstanceOf() {
check(
InstanceOfExample::listInstanceOf,
eq(2),
{ _, r -> r == null },
{ _, r -> r!!::class == java.util.ArrayList::class }
)
}

@Test
fun testDequeInstanceOf() {
check(
InstanceOfExample::dequeInstanceOf,
eq(2),
{ _, r -> r == null },
{ _, r -> r!!::class == java.util.LinkedList::class }
)
}

@Test
fun testAbstractSeqListInstanceOf() {
check(
InstanceOfExample::abstractSequentialListInstanceOf,
eq(2),
{ _, r -> r == null },
{ _, r -> r!!::class == java.util.LinkedList::class }
)
}

@Test
fun testSetInstanceOf() {
check(
InstanceOfExample::setInstanceOf,
eq(2),
{ _, r -> r == null },
{ _, r -> r!!::class == java.util.LinkedHashSet::class }
)
}

@Test
fun testMapInstanceOf() {
check(
InstanceOfExample::mapInstanceOf,
eq(2),
{ _, r -> r == null },
{ _, r -> r!!::class == java.util.LinkedHashMap::class }
)
}

private inline fun <reified T : Any> Any?.isInstanceOfArray() =
(this as? Array<*>)?.run { T::class.java.isAssignableFrom(this::class.java.componentType) } == true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import org.utbot.framework.plugin.api.UtModel
import org.utbot.framework.plugin.api.UtNullModel
import org.utbot.framework.plugin.api.UtPrimitiveModel
import org.utbot.framework.plugin.api.getIdOrThrow
import org.utbot.framework.plugin.api.idOrNull
import org.utbot.framework.plugin.api.util.id
import org.utbot.framework.plugin.api.util.objectArrayClassId
import org.utbot.framework.plugin.api.util.objectClassId
Expand All @@ -34,6 +33,7 @@ import soot.Scene
import soot.SootClass
import soot.SootField
import soot.SootMethod
import soot.Type

val rangeModifiableArrayId: ClassId = RangeModifiableUnlimitedArray::class.id

Expand Down Expand Up @@ -264,6 +264,13 @@ class RangeModifiableUnlimitedArrayWrapper : WrapperInterface {
return resultModel
}

override fun getPossibleConcreteTypes(type: Type): Set<Type> {
val possibleObjectTypes = Scene.v().classes.map { it.type }
return possibleObjectTypes.mapTo(mutableSetOf()) {
it.arrayType
}
Comment on lines +268 to +271
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now it contains all the types, including interfaces, abstract classes, artificial entities, our own classes, etc.

}

companion object {
internal val rangeModifiableArrayClass: SootClass
get() = Scene.v().getSootClass(rangeModifiableArrayId.name)
Expand Down Expand Up @@ -415,6 +422,9 @@ class AssociativeArrayWrapper : WrapperInterface {
return model
}

override fun getPossibleConcreteTypes(type: Type): Set<Type> =
setOf(associativeArrayClass.type)

private fun Traverser.getStorageArrayField(addr: UtAddrExpression) =
getArrayField(addr, associativeArrayClass, storageField)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,21 @@ import org.utbot.framework.plugin.api.UtNullModel
import org.utbot.framework.plugin.api.UtStatementModel
import org.utbot.framework.plugin.api.classId
import org.utbot.framework.plugin.api.getIdOrThrow
import org.utbot.framework.util.graph
import org.utbot.framework.plugin.api.id
import org.utbot.framework.plugin.api.util.booleanClassId
import org.utbot.framework.plugin.api.util.constructorId
import org.utbot.framework.plugin.api.util.id
import org.utbot.framework.plugin.api.util.methodId
import org.utbot.framework.plugin.api.util.objectClassId
import org.utbot.framework.util.graph
import org.utbot.framework.util.nextModelName
import soot.IntType
import soot.RefType
import soot.Scene
import soot.SootClass
import soot.SootField
import soot.SootMethod
import soot.Type

abstract class BaseOverriddenWrapper(protected val overriddenClassName: String) : WrapperInterface {
val overriddenClass: SootClass = Scene.v().getSootClass(overriddenClassName)
Expand Down Expand Up @@ -130,6 +131,9 @@ abstract class BaseContainerWrapper(containerClassName: String) : BaseOverridden
}
}

override fun getPossibleConcreteTypes(type: Type): Set<Type> =
setOf(chooseClassIdWithConstructor(type.classId).sootType)

/**
* Method returns list of parameter models that will be passed to [modificationMethodId]
* while construction modification chain in [UtAssembleModel] for the specified [wrapper]
Expand Down Expand Up @@ -398,21 +402,6 @@ private val UT_GENERIC_ASSOCIATIVE_CLASS
private val UT_GENERIC_ASSOCIATIVE_SET_EQUAL_GENERIC_TYPE_SIGNATURE =
UT_GENERIC_ASSOCIATIVE_CLASS.getMethodByName(UtGenericAssociative<*, *>::setEqualGenericType.name).signature

val ARRAY_LIST_TYPE: RefType
get() = Scene.v().getSootClass(java.util.ArrayList::class.java.canonicalName).type
val LINKED_LIST_TYPE: RefType
get() = Scene.v().getSootClass(java.util.LinkedList::class.java.canonicalName).type

val LINKED_HASH_SET_TYPE: RefType
get() = Scene.v().getSootClass(java.util.LinkedHashSet::class.java.canonicalName).type
val HASH_SET_TYPE: RefType
get() = Scene.v().getSootClass(java.util.HashSet::class.java.canonicalName).type

val LINKED_HASH_MAP_TYPE: RefType
get() = Scene.v().getSootClass(java.util.LinkedHashMap::class.java.canonicalName).type
val HASH_MAP_TYPE: RefType
get() = Scene.v().getSootClass(java.util.HashMap::class.java.canonicalName).type

val STREAM_TYPE: RefType
get() = Scene.v().getSootClass(java.util.stream.Stream::class.java.canonicalName).type

Expand Down
26 changes: 18 additions & 8 deletions utbot-framework/src/main/kotlin/org/utbot/engine/Extensions.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
package org.utbot.engine

import com.google.common.collect.BiMap
import java.lang.reflect.ParameterizedType
import java.util.ArrayDeque
import java.util.Deque
import java.util.LinkedList
import java.util.Queue
import java.util.concurrent.ConcurrentHashMap
import kotlinx.collections.immutable.PersistentMap
import kotlinx.collections.immutable.persistentHashMapOf
import org.utbot.api.mock.UtMock
import org.utbot.engine.pc.UtAddrExpression
import org.utbot.engine.pc.UtArraySort
Expand Down Expand Up @@ -33,8 +41,11 @@ import org.utbot.engine.pc.mkString
import org.utbot.engine.pc.toSort
import org.utbot.framework.UtSettings.checkNpeInNestedMethods
import org.utbot.framework.UtSettings.checkNpeInNestedNotPrivateMethods
import org.utbot.framework.plugin.api.ClassId
import org.utbot.framework.plugin.api.FieldId
import org.utbot.framework.plugin.api.id
import org.utbot.framework.plugin.api.util.isArray
import org.utbot.framework.plugin.api.util.isPrimitive
import soot.ArrayType
import soot.PrimType
import soot.RefLikeType
Expand All @@ -60,14 +71,6 @@ import soot.jimple.internal.JStaticInvokeExpr
import soot.jimple.internal.JVirtualInvokeExpr
import soot.jimple.internal.JimpleLocal
import soot.tagkit.ArtificialEntityTag
import java.lang.reflect.ParameterizedType
import java.util.ArrayDeque
import java.util.Deque
import java.util.LinkedList
import java.util.Queue
import java.util.concurrent.ConcurrentHashMap
import kotlinx.collections.immutable.PersistentMap
import kotlinx.collections.immutable.persistentHashMapOf

val JIdentityStmt.lines: String
get() = tags.joinToString { "$it" }
Expand Down Expand Up @@ -424,3 +427,10 @@ val SootMethod.isUtMockAssumeOrExecuteConcretely
*/
val SootMethod.isPreconditionCheckMethod
get() = declaringClass.isOverridden && name == "preconditionCheck"

val ClassId.sootType: Type
get() = when {
isPrimitive -> Scene.v().getType(name)
SBOne-Kenobi marked this conversation as resolved.
Show resolved Hide resolved
isArray -> elementClassId!!.sootType.arrayType
else -> Scene.v().getSootClass(canonicalName).type
}
15 changes: 9 additions & 6 deletions utbot-framework/src/main/kotlin/org/utbot/engine/Mocks.kt
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package org.utbot.engine

import java.util.concurrent.atomic.AtomicInteger
import kotlin.reflect.KFunction2
import kotlin.reflect.KFunction5
import kotlinx.collections.immutable.persistentListOf
import org.utbot.api.mock.UtMock
import org.utbot.common.packageName
import org.utbot.engine.overrides.UtArrayMock
import org.utbot.engine.overrides.UtLogicMock
import org.utbot.engine.overrides.UtOverrideMock
import org.utbot.engine.pc.UtAddrExpression
import org.utbot.engine.util.mockListeners.MockListenerController
import org.utbot.framework.plugin.api.ClassId
import org.utbot.framework.plugin.api.FieldId
import org.utbot.framework.plugin.api.MethodId
Expand All @@ -14,17 +18,13 @@ import org.utbot.framework.plugin.api.id
import org.utbot.framework.plugin.api.util.id
import org.utbot.framework.plugin.api.util.isRefType
import org.utbot.framework.util.executableId
import java.util.concurrent.atomic.AtomicInteger
import kotlin.reflect.KFunction2
import kotlin.reflect.KFunction5
import kotlinx.collections.immutable.persistentListOf
import org.utbot.engine.util.mockListeners.MockListenerController
import org.utbot.framework.util.isInaccessibleViaReflection
import soot.BooleanType
import soot.RefType
import soot.Scene
import soot.SootClass
import soot.SootMethod
import soot.Type

/**
* Generates mock with address provided.
Expand Down Expand Up @@ -307,6 +307,9 @@ class UtMockWrapper(
override fun value(resolver: Resolver, wrapper: ObjectValue): UtModel =
TODO("value on mock called: $this")

override fun getPossibleConcreteTypes(type: Type): Set<Type> =
setOf(this.type)

override fun toString() = "UtMock(type=$type, target=$mockInfo)"
}

Expand Down
52 changes: 32 additions & 20 deletions utbot-framework/src/main/kotlin/org/utbot/engine/ObjectWrappers.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
package org.utbot.engine

import java.util.Optional
import java.util.OptionalDouble
import java.util.OptionalInt
import java.util.OptionalLong
import java.util.concurrent.CopyOnWriteArrayList
import kotlin.reflect.KClass
import org.utbot.common.WorkaroundReason.MAKE_SYMBOLIC
import org.utbot.common.workaround
import org.utbot.engine.UtListClass.UT_ARRAY_LIST
Expand Down Expand Up @@ -34,12 +40,7 @@ import soot.RefType
import soot.Scene
import soot.SootClass
import soot.SootMethod
import java.util.Optional
import java.util.OptionalDouble
import java.util.OptionalInt
import java.util.OptionalLong
import java.util.concurrent.CopyOnWriteArrayList
import kotlin.reflect.KClass
import soot.Type

typealias TypeToBeWrapped = RefType
typealias WrapperType = RefType
Expand Down Expand Up @@ -151,15 +152,15 @@ private val wrappers = mapOf(
},

// list wrappers
wrap(java.util.List::class) { _, addr -> objectValue(ARRAY_LIST_TYPE, addr, ListWrapper(UT_ARRAY_LIST)) },
wrap(java.util.AbstractList::class) { _, addr -> objectValue(ARRAY_LIST_TYPE, addr, ListWrapper(UT_ARRAY_LIST)) },
wrap(java.util.ArrayList::class) { _, addr -> objectValue(ARRAY_LIST_TYPE, addr, ListWrapper(UT_ARRAY_LIST)) },
wrap(java.util.List::class) { type, addr -> objectValue(type, addr, ListWrapper(UT_ARRAY_LIST)) },
wrap(java.util.AbstractList::class) { type, addr -> objectValue(type, addr, ListWrapper(UT_ARRAY_LIST)) },
wrap(java.util.ArrayList::class) { type, addr -> objectValue(type, addr, ListWrapper(UT_ARRAY_LIST)) },


wrap(CopyOnWriteArrayList::class) { type, addr -> objectValue(type, addr, ListWrapper(UT_ARRAY_LIST)) },

wrap(java.util.LinkedList::class) { _, addr -> objectValue(LINKED_LIST_TYPE, addr, ListWrapper(UT_LINKED_LIST)) },
wrap(java.util.AbstractSequentialList::class) { _, addr -> objectValue(LINKED_LIST_TYPE, addr, ListWrapper(UT_LINKED_LIST)) },
wrap(java.util.LinkedList::class) { type, addr -> objectValue(type, addr, ListWrapper(UT_LINKED_LIST)) },
wrap(java.util.AbstractSequentialList::class) { type, addr -> objectValue(type, addr, ListWrapper(UT_LINKED_LIST)) },

// queue, deque wrappers
wrap(java.util.ArrayDeque::class) { type, addr ->
Expand All @@ -179,17 +180,17 @@ private val wrappers = mapOf(
},

// set wrappers
wrap(java.util.Set::class) { _, addr -> objectValue(LINKED_HASH_SET_TYPE, addr, SetWrapper()) },
wrap(java.util.AbstractSet::class) { _, addr -> objectValue(LINKED_HASH_SET_TYPE, addr, SetWrapper()) },
wrap(java.util.HashSet::class) { _, addr -> objectValue(HASH_SET_TYPE, addr, SetWrapper()) },
wrap(java.util.LinkedHashSet::class) { _, addr -> objectValue(LINKED_HASH_SET_TYPE, addr, SetWrapper()) },
wrap(java.util.Set::class) { type, addr -> objectValue(type, addr, SetWrapper()) },
wrap(java.util.AbstractSet::class) { type, addr -> objectValue(type, addr, SetWrapper()) },
wrap(java.util.HashSet::class) { type, addr -> objectValue(type, addr, SetWrapper()) },
wrap(java.util.LinkedHashSet::class) { type, addr -> objectValue(type, addr, SetWrapper()) },

// map wrappers
wrap(java.util.Map::class) { _, addr -> objectValue(LINKED_HASH_MAP_TYPE, addr, MapWrapper()) },
wrap(java.util.AbstractMap::class) { _, addr -> objectValue(LINKED_HASH_MAP_TYPE, addr, MapWrapper()) },
wrap(java.util.LinkedHashMap::class) { _, addr -> objectValue(LINKED_HASH_MAP_TYPE, addr, MapWrapper()) },
wrap(java.util.HashMap::class) { _, addr -> objectValue(HASH_MAP_TYPE, addr, MapWrapper()) },
wrap(java.util.concurrent.ConcurrentHashMap::class) { _, addr -> objectValue(HASH_MAP_TYPE, addr, MapWrapper()) },
wrap(java.util.Map::class) { type, addr -> objectValue(type, addr, MapWrapper()) },
wrap(java.util.AbstractMap::class) { type, addr -> objectValue(type, addr, MapWrapper()) },
wrap(java.util.LinkedHashMap::class) { type, addr -> objectValue(type, addr, MapWrapper()) },
wrap(java.util.HashMap::class) { type, addr -> objectValue(type, addr, MapWrapper()) },
wrap(java.util.concurrent.ConcurrentHashMap::class) { type, addr -> objectValue(type, addr, MapWrapper()) },

// stream wrappers
wrap(java.util.stream.BaseStream::class) { _, addr -> objectValue(STREAM_TYPE, addr, CommonStreamWrapper()) },
Expand Down Expand Up @@ -222,6 +223,14 @@ interface WrapperInterface {
): List<InvokeResult>

fun value(resolver: Resolver, wrapper: ObjectValue): UtModel

/**
* Returns list of possible concrete types that can be produced by [value] method.
* Used for wrapper initialization.
*
* @param type target type to wrap
*/
fun getPossibleConcreteTypes(type: Type): Set<Type>
}

// TODO: perhaps we have to have wrapper around concrete value here
Expand Down Expand Up @@ -252,4 +261,7 @@ data class ThrowableWrapper(val throwable: Throwable) : WrapperInterface {

return UtAssembleModel(addr, classId, modelName, instantiationCall)
}

override fun getPossibleConcreteTypes(type: Type): Set<Type> =
setOf(throwable.javaClass.id.sootType)
}
Loading