Skip to content

Commit 66470e0

Browse files
committed
Add StateBeforeAwareIdGenerator
1 parent 9b9a0b3 commit 66470e0

File tree

1 file changed

+103
-0
lines changed

1 file changed

+103
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
package org.utbot.instrumentation.instrumentation.execution.constructors
2+
3+
import org.utbot.framework.plugin.api.UtArrayModel
4+
import org.utbot.framework.plugin.api.UtAssembleModel
5+
import org.utbot.framework.plugin.api.UtClassRefModel
6+
import org.utbot.framework.plugin.api.UtCompositeModel
7+
import org.utbot.framework.plugin.api.UtCustomModel
8+
import org.utbot.framework.plugin.api.UtDirectSetFieldModel
9+
import org.utbot.framework.plugin.api.UtEnumConstantModel
10+
import org.utbot.framework.plugin.api.UtLambdaModel
11+
import org.utbot.framework.plugin.api.UtModel
12+
import org.utbot.framework.plugin.api.UtNewInstanceInstrumentation
13+
import org.utbot.framework.plugin.api.UtNullModel
14+
import org.utbot.framework.plugin.api.UtPrimitiveModel
15+
import org.utbot.framework.plugin.api.UtReferenceModel
16+
import org.utbot.framework.plugin.api.UtStatementCallModel
17+
import org.utbot.framework.plugin.api.UtStatementModel
18+
import org.utbot.framework.plugin.api.UtStaticMethodInstrumentation
19+
import org.utbot.framework.plugin.api.UtVoidModel
20+
import org.utbot.instrumentation.instrumentation.execution.UtConcreteExecutionData
21+
import java.util.*
22+
23+
class StateBeforeAwareIdGenerator(preExistingModels: Collection<UtModel>) {
24+
private val seenIds = mutableSetOf<Int>()
25+
26+
// there's no `IdentityHashSet`, so we use `IdentityHashMap` with dummy values
27+
private val seenModels = IdentityHashMap<UtModel, Unit>()
28+
29+
private var nextId = 0
30+
31+
init {
32+
collectIds(preExistingModels)
33+
}
34+
35+
private fun collectIds(models: Collection<UtModel>) =
36+
models.forEach { collectIds(it) }
37+
38+
private fun collectIds(model: UtModel) {
39+
if (model !in seenModels) {
40+
seenModels[model] = Unit
41+
(model as? UtReferenceModel)?.id?.let { seenIds.add(it) }
42+
when (model) {
43+
is UtNullModel,
44+
is UtPrimitiveModel,
45+
is UtEnumConstantModel,
46+
is UtClassRefModel,
47+
is UtVoidModel -> {}
48+
is UtCompositeModel -> {
49+
collectIds(model.fields.values)
50+
model.mocks.values.forEach { collectIds(it) }
51+
}
52+
is UtArrayModel -> {
53+
collectIds(model.constModel)
54+
collectIds(model.stores.values)
55+
}
56+
is UtAssembleModel -> {
57+
model.origin?.let { collectIds(it) }
58+
collectIds(model.instantiationCall)
59+
model.modificationsChain.forEach { collectIds(it) }
60+
}
61+
is UtCustomModel -> {
62+
model.origin?.let { collectIds(it) }
63+
collectIds(model.dependencies)
64+
}
65+
is UtLambdaModel -> {
66+
collectIds(model.capturedValues)
67+
}
68+
else -> error("Can't collect ids from $model")
69+
}
70+
}
71+
}
72+
73+
private fun collectIds(call: UtStatementModel): Unit = when (call) {
74+
is UtStatementCallModel -> {
75+
call.instance?.let { collectIds(it) }
76+
collectIds(call.params)
77+
}
78+
is UtDirectSetFieldModel -> {
79+
collectIds(call.instance)
80+
collectIds(call.fieldModel)
81+
}
82+
}
83+
84+
fun createId(): Int {
85+
while (nextId in seenIds) nextId++
86+
return nextId++
87+
}
88+
89+
companion object {
90+
fun fromUtConcreteExecutionData(data: UtConcreteExecutionData): StateBeforeAwareIdGenerator =
91+
StateBeforeAwareIdGenerator(
92+
listOfNotNull(data.stateBefore.thisInstance) +
93+
data.stateBefore.parameters +
94+
data.stateBefore.statics.values +
95+
data.instrumentation.flatMap {
96+
when (it) {
97+
is UtNewInstanceInstrumentation -> it.instances
98+
is UtStaticMethodInstrumentation -> it.values
99+
}
100+
}
101+
)
102+
}
103+
}

0 commit comments

Comments
 (0)