@@ -126,11 +126,13 @@ import org.utbot.framework.plugin.api.TypeReplacementMode.KnownImplementor
126126import org.utbot.framework.plugin.api.TypeReplacementMode.NoImplementors
127127import org.utbot.framework.plugin.api.classId
128128import org.utbot.framework.plugin.api.id
129+ import org.utbot.framework.plugin.api.isAbstractType
129130import org.utbot.framework.plugin.api.util.executable
130131import org.utbot.framework.plugin.api.util.findFieldByIdOrNull
131132import org.utbot.framework.plugin.api.util.jField
132133import org.utbot.framework.plugin.api.util.jClass
133134import org.utbot.framework.plugin.api.util.id
135+ import org.utbot.framework.plugin.api.util.isAbstract
134136import org.utbot.framework.plugin.api.util.isConstructor
135137import org.utbot.framework.plugin.api.util.utContext
136138import org.utbot.framework.util.executableId
@@ -1375,6 +1377,7 @@ class Traverser(
13751377 mockInfoGenerator : UtMockInfoGenerator ? = null
13761378 ): ObjectValue {
13771379 touchAddress(addr)
1380+ val nullEqualityConstraint = mkEq(addr, nullObjectAddr)
13781381
13791382 // Some types (e.g., interfaces) need to be mocked or replaced with the concrete implementor.
13801383 // Typically, this implementor is selected by SMT solver later.
@@ -1397,8 +1400,6 @@ class Traverser(
13971400 return ObjectValue (typeStorage, addr)
13981401 }
13991402
1400- val nullEqualityConstraint = mkEq(addr, nullObjectAddr)
1401-
14021403 if (mockInfoGenerator != null ) {
14031404 val mockInfo = mockInfoGenerator.generate(addr)
14041405
@@ -1499,21 +1500,16 @@ class Traverser(
14991500 " but there is no mock info generator provided to construct a mock value."
15001501 }
15011502
1502- return createMockedObject(addr, type, mockInfoGenerator)
1503+ return createMockedObject(addr, type, mockInfoGenerator, nullEqualityConstraint )
15031504 }
15041505
15051506 val concreteImplementation = when (applicationContext.typeReplacementMode) {
1506- AnyImplementor -> {
1507- val isMockConstraint = mkEq(typeRegistry.isMock(addr), UtFalse )
1508-
1509- queuedSymbolicStateUpdates + = typeHardConstraint
1510- queuedSymbolicStateUpdates + = mkOr(isMockConstraint, nullEqualityConstraint).asHardConstraint()
1507+ AnyImplementor -> findConcreteImplementation(addr, type, typeHardConstraint, nullEqualityConstraint)
15111508
1512- // If we have this$0 with UtArrayList type, we have to create such instance.
1513- // We should create an object with typeStorage of all possible real types and concrete implementation
1514- // Otherwise we'd have either a wrong type in the resolver, or missing method like 'preconditionCheck'.
1515- wrapperToClass[type]?.first()?.let { wrapper(it, addr) }?.concrete
1516- }
1509+ // If our type is not abstract, both in `KnownImplementors` and `NoImplementors` mode,
1510+ // we should just still use concrete implementation that represents itself
1511+ //
1512+ // Otherwise:
15171513 // In case of `KnownImplementor` mode we should have already tried to replace type using `replaceTypeIfNeeded`.
15181514 // However, this replacement attempt might be unsuccessful even if some possible concrete types are present.
15191515 // For example, we may have two concrete implementors present in Spring bean definitions, so we do not know
@@ -1523,8 +1519,12 @@ class Traverser(
15231519 // Mocking can be impossible here as there are no guaranties that `mockInfoGenerator` is instantiated.
15241520 KnownImplementor ,
15251521 NoImplementors -> {
1522+ if (! type.isAbstractType) {
1523+ findConcreteImplementation(addr, type, typeHardConstraint, nullEqualityConstraint)
1524+ }
1525+
15261526 mockInfoGenerator?.let {
1527- return createMockedObject(addr, type, it)
1527+ return createMockedObject(addr, type, it, nullEqualityConstraint )
15281528 }
15291529
15301530 queuedSymbolicStateUpdates + = mkFalse().asHardConstraint()
@@ -1535,13 +1535,29 @@ class Traverser(
15351535 return ObjectValue (typeStorage, addr, concreteImplementation)
15361536 }
15371537
1538+ private fun findConcreteImplementation (
1539+ addr : UtAddrExpression ,
1540+ type : RefType ,
1541+ typeHardConstraint : HardConstraint ,
1542+ nullEqualityConstraint : UtBoolExpression ,
1543+ ): Concrete ? {
1544+ val isMockConstraint = mkEq(typeRegistry.isMock(addr), UtFalse )
1545+
1546+ queuedSymbolicStateUpdates + = typeHardConstraint
1547+ queuedSymbolicStateUpdates + = mkOr(isMockConstraint, nullEqualityConstraint).asHardConstraint()
1548+
1549+ // If we have this$0 with UtArrayList type, we have to create such instance.
1550+ // We should create an object with typeStorage of all possible real types and concrete implementation
1551+ // Otherwise we'd have either a wrong type in the resolver, or missing method like 'preconditionCheck'.
1552+ return wrapperToClass[type]?.first()?.let { wrapper(it, addr) }?.concrete
1553+ }
1554+
15381555 private fun createMockedObject (
15391556 addr : UtAddrExpression ,
15401557 type : RefType ,
15411558 mockInfoGenerator : UtMockInfoGenerator ,
1559+ nullEqualityConstraint : UtBoolExpression ,
15421560 ): ObjectValue {
1543- val nullEqualityConstraint = mkEq(addr, nullObjectAddr)
1544-
15451561 val mockInfo = mockInfoGenerator.generate(addr)
15461562 val mockedObjectInfo = mocker.forceMock(type, mockInfoGenerator.generate(addr))
15471563
0 commit comments