@@ -121,7 +121,9 @@ import org.utbot.framework.plugin.api.ClassId
121121import org.utbot.framework.plugin.api.ExecutableId
122122import org.utbot.framework.plugin.api.FieldId
123123import org.utbot.framework.plugin.api.MethodId
124- import org.utbot.framework.plugin.api.SpringApplicationContext
124+ import org.utbot.framework.plugin.api.TypeReplacementMode.AnyImplementor
125+ import org.utbot.framework.plugin.api.TypeReplacementMode.KnownImplementor
126+ import org.utbot.framework.plugin.api.TypeReplacementMode.NoImplementors
125127import org.utbot.framework.plugin.api.classId
126128import org.utbot.framework.plugin.api.id
127129import org.utbot.framework.plugin.api.util.executable
@@ -1365,7 +1367,7 @@ class Traverser(
13651367 traverseException(current, symException)
13661368 }
13671369
1368- // TODO HACK violation of encapsulation
1370+ // TODO: HACK violation of encapsulation
13691371 fun createObject (
13701372 addr : UtAddrExpression ,
13711373 type : RefType ,
@@ -1374,8 +1376,13 @@ class Traverser(
13741376 ): ObjectValue {
13751377 touchAddress(addr)
13761378
1377- val concreteClassId = applicationContext.replaceTypeIfNeeded(type)
1378- concreteClassId?.let {
1379+ val replacedClassId = when (applicationContext.typeReplacementMode) {
1380+ KnownImplementor -> applicationContext.replaceTypeIfNeeded(type)
1381+ AnyImplementor ,
1382+ NoImplementors -> null
1383+ }
1384+
1385+ replacedClassId?.let {
13791386 val sootType = typeResolver.classOrDefault(it.canonicalName)
13801387 val typeStorage = typeResolver.constructTypeStorage(sootType, useConcreteType = false )
13811388
@@ -1481,58 +1488,66 @@ class Traverser(
14811488 return it
14821489 }
14831490
1484- // In Spring application we may rely on concrete types obtained from bean definitions only,
1485- // and this potential replacement has already been suggested in the beginning of the method
1486- val useConcreteTypes = applicationContext !is SpringApplicationContext
1487-
1488- if (useConcreteTypes && typeStorage.possibleConcreteTypes.any()) {
1489- // If we have this$0 with UtArrayList type, we have to create such instance.
1490- // We should create an object with typeStorage of all possible real types and concrete implementation
1491- // Otherwise we'd have either a wrong type in the resolver, or missing method like 'preconditionCheck'.
1492- val concreteImplementation = wrapperToClass[type]?.first()?.let { wrapper(it, addr) }?.concrete
1493- val isMockConstraint = mkEq(typeRegistry.isMock(addr), UtFalse )
1494-
1495- queuedSymbolicStateUpdates + = typeHardConstraint
1496- queuedSymbolicStateUpdates + = mkOr(isMockConstraint, nullEqualityConstraint).asHardConstraint()
1491+ if (typeStorage.possibleConcreteTypes.isEmpty()) {
1492+ requireNotNull(mockInfoGenerator) {
1493+ " An object with $addr and $type doesn't have concrete possible types," +
1494+ " but there is no mock info generator provided to construct a mock value."
1495+ }
14971496
1498- return ObjectValue (typeStorage, addr, concreteImplementation)
1499- }
1497+ val mockInfo = mockInfoGenerator.generate(addr)
1498+ val mockedObjectInfo = mocker.forceMock(type, mockInfoGenerator.generate(addr))
1499+
1500+ val mockedObject: ObjectValue = when (mockedObjectInfo) {
1501+ is NoMock -> error(" Value must be mocked after the force mock" )
1502+ is ExpectedMock -> mockedObjectInfo.value
1503+ is UnexpectedMock -> {
1504+ // if mock occurs, but it is unexpected due to some reasons
1505+ // (e.g. we do not have mock framework installed),
1506+ // we can only generate a test that uses null value for mocked object
1507+ queuedSymbolicStateUpdates + = nullEqualityConstraint.asHardConstraint()
1508+
1509+ mockedObjectInfo.value
1510+ }
1511+ }
15001512
1501- requireNotNull(mockInfoGenerator) {
1502- " An object with $addr and $type doesn't have concrete possible types," +
1503- " but there is no mock info generator provided to construct a mock value."
1504- }
1513+ if (mockedObjectInfo is UnexpectedMock ) {
1514+ return mockedObject
1515+ }
15051516
1506- val mockInfo = mockInfoGenerator.generate(addr)
1507- val mockedObjectInfo = mocker.forceMock(type, mockInfoGenerator.generate(addr))
1517+ queuedSymbolicStateUpdates + = MemoryUpdate (mockInfos = persistentListOf(MockInfoEnriched (mockInfo)))
15081518
1509- val mockedObject: ObjectValue = when (mockedObjectInfo) {
1510- is NoMock -> error(" Value must be mocked after the force mock" )
1511- is ExpectedMock -> mockedObjectInfo.value
1512- is UnexpectedMock -> {
1513- // if mock occurs, but it is unexpected due to some reasons
1514- // (e.g. we do not have mock framework installed),
1515- // we can only generate a test that uses null value for mocked object
1516- queuedSymbolicStateUpdates + = nullEqualityConstraint.asHardConstraint()
1519+ // add typeConstraint for mocked object. It's a declared type of the object.
1520+ val typeConstraint = typeRegistry.typeConstraint(addr, mockedObject.typeStorage).all()
1521+ val isMockConstraint = mkEq(typeRegistry.isMock(mockedObject.addr), UtTrue )
15171522
1518- mockedObjectInfo.value
1519- }
1520- }
1523+ queuedSymbolicStateUpdates + = typeConstraint.asHardConstraint()
1524+ queuedSymbolicStateUpdates + = mkOr(isMockConstraint, nullEqualityConstraint).asHardConstraint()
15211525
1522- if (mockedObjectInfo is UnexpectedMock ) {
15231526 return mockedObject
15241527 }
15251528
1526- queuedSymbolicStateUpdates + = MemoryUpdate (mockInfos = persistentListOf(MockInfoEnriched (mockInfo)))
1529+ val concreteImplementation = when (applicationContext.typeReplacementMode) {
1530+ AnyImplementor -> {
1531+ val isMockConstraint = mkEq(typeRegistry.isMock(addr), UtFalse )
15271532
1528- // add typeConstraint for mocked object. It's a declared type of the object.
1529- val typeConstraint = typeRegistry.typeConstraint(addr, mockedObject.typeStorage).all()
1530- val isMockConstraint = mkEq(typeRegistry.isMock(mockedObject.addr), UtTrue )
1533+ queuedSymbolicStateUpdates + = typeHardConstraint
1534+ queuedSymbolicStateUpdates + = mkOr(isMockConstraint, nullEqualityConstraint).asHardConstraint()
15311535
1532- queuedSymbolicStateUpdates + = typeConstraint.asHardConstraint()
1533- queuedSymbolicStateUpdates + = mkOr(isMockConstraint, nullEqualityConstraint).asHardConstraint()
1536+ // If we have this$0 with UtArrayList type, we have to create such instance.
1537+ // We should create an object with typeStorage of all possible real types and concrete implementation
1538+ // Otherwise we'd have either a wrong type in the resolver, or missing method like 'preconditionCheck'.
1539+ wrapperToClass[type]?.first()?.let { wrapper(it, addr) }?.concrete
1540+ }
1541+ // In case of known implementor we should have already tried to replace type using `replaceTypeIfNeeded`.
1542+ KnownImplementor ,
1543+ // If no implementors are allowed, we should have already generated a mock object.
1544+ NoImplementors -> {
1545+ queuedSymbolicStateUpdates + = mkFalse().asHardConstraint()
1546+ null
1547+ }
1548+ }
15341549
1535- return mockedObject
1550+ return ObjectValue (typeStorage, addr, concreteImplementation)
15361551 }
15371552
15381553
0 commit comments