Skip to content

Commit f16b931

Browse files
authored
Add method body with cfg and locals (#346)
1 parent 0a50288 commit f16b931

3 files changed

Lines changed: 45 additions & 9 deletions

File tree

jacodb-ets/src/main/kotlin/org/jacodb/ets/dto/Convert.kt

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -143,15 +143,22 @@ class EtsMethodBuilder(
143143
typeParameters: List<EtsType> = emptyList(),
144144
modifiers: EtsModifiers = EtsModifiers.EMPTY,
145145
decorators: List<EtsDecorator> = emptyList(),
146+
locals: List<EtsLocal> = emptyList(),
146147
) {
147-
private val method = EtsMethodImpl(signature, typeParameters, modifiers, decorators)
148+
private val locals = locals.toMutableList()
149+
150+
private val method = EtsMethodImpl(signature, typeParameters, modifiers, decorators).also {
151+
it.body.locals = this.locals
152+
}
148153

149154
private lateinit var currentStmts: MutableList<EtsStmt>
150155

151156
private var freeTempLocal: Int = 0
152157

153158
private fun newTempLocal(): EtsLocal {
154-
return EtsLocal("_tmp${freeTempLocal++}")
159+
val local = EtsLocal("_tmp${freeTempLocal++}")
160+
this@EtsMethodBuilder.locals += local
161+
return local
155162
}
156163

157164
private fun loc(): EtsStmtLocation {
@@ -163,7 +170,7 @@ class EtsMethodBuilder(
163170
fun build(cfgDto: CfgDto): EtsMethod {
164171
require(!built) { "Method has already been built" }
165172
val cfg = cfgDto.toEtsCfg()
166-
method._cfg = cfg
173+
method.body.cfg = cfg
167174
built = true
168175
return method
169176
}
@@ -682,6 +689,7 @@ fun MethodDto.toEtsMethod(): EtsMethod {
682689
typeParameters = typeParameters,
683690
modifiers = modifiers,
684691
decorators = decorators,
692+
locals = body.locals.map { it.toEtsLocal() },
685693
)
686694
return builder.build(body.cfg)
687695
} else {

jacodb-ets/src/main/kotlin/org/jacodb/ets/model/Method.kt

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import org.jacodb.api.common.CommonMethod
2323
interface EtsMethod : Base, CommonMethod {
2424
val signature: EtsMethodSignature
2525
val typeParameters: List<EtsType>
26-
val cfg: EtsBlockCfg
26+
val body: EtsMethodBody
2727

2828
val enclosingClass: EtsClass?
2929

@@ -36,21 +36,36 @@ interface EtsMethod : Base, CommonMethod {
3636
override val returnType: EtsType
3737
get() = signature.returnType
3838

39+
val cfg: EtsBlockCfg
40+
get() = body.cfg
41+
42+
val locals: List<EtsLocal>
43+
get() = body.locals
44+
3945
override fun flowGraph(): EtsBytecodeGraph<EtsStmt> {
4046
return cfg
4147
}
4248
}
4349

50+
class EtsMethodBody(
51+
var cfg: EtsBlockCfg = EtsBlockCfg.EMPTY,
52+
var locals: List<EtsLocal> = emptyList(),
53+
)
54+
4455
class EtsMethodImpl(
4556
override val signature: EtsMethodSignature,
4657
override val typeParameters: List<EtsType> = emptyList(),
4758
override val modifiers: EtsModifiers = EtsModifiers.EMPTY,
4859
override val decorators: List<EtsDecorator> = emptyList(),
4960
) : EtsMethod {
50-
var _cfg: EtsBlockCfg? = null
51-
52-
override val cfg: EtsBlockCfg
53-
get() = _cfg ?: EtsBlockCfg.EMPTY
61+
override val body: EtsMethodBody = EtsMethodBody()
62+
63+
@Deprecated("Use body.cfg instead", ReplaceWith("body.cfg"))
64+
var _cfg: EtsBlockCfg
65+
get() = body.cfg
66+
set(value) {
67+
body.cfg = value
68+
}
5469

5570
override var enclosingClass: EtsClass? = null
5671

jacodb-ets/src/test/kotlin/org/jacodb/ets/test/EtsCfgDslTest.kt

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@ import org.jacodb.ets.dsl.param
2424
import org.jacodb.ets.dsl.program
2525
import org.jacodb.ets.dsl.toBlockCfg
2626
import org.jacodb.ets.dsl.toDot
27+
import org.jacodb.ets.model.EtsAssignStmt
2728
import org.jacodb.ets.model.EtsClassSignature
2829
import org.jacodb.ets.model.EtsFileSignature
30+
import org.jacodb.ets.model.EtsLocal
2931
import org.jacodb.ets.model.EtsMethodImpl
3032
import org.jacodb.ets.model.EtsMethodParameter
3133
import org.jacodb.ets.model.EtsMethodSignature
@@ -35,6 +37,8 @@ import org.jacodb.ets.utils.linearize
3537
import org.jacodb.ets.utils.toDot
3638
import org.jacodb.ets.utils.toEtsBlockCfg
3739
import org.junit.jupiter.api.Test
40+
import kotlin.test.assertContentEquals
41+
import kotlin.test.assertEquals
3842

3943
class EtsCfgDslTest {
4044
@Test
@@ -79,6 +83,15 @@ class EtsCfgDslTest {
7983
val etsCfg = etsBlockCfg.linearize()
8084
println("etsCfg:\n${etsCfg.toDot()}")
8185

82-
method._cfg = etsBlockCfg
86+
method.body.cfg = etsBlockCfg
87+
method.body.locals = etsBlockCfg.stmts
88+
.filterIsInstance<EtsAssignStmt>()
89+
.mapNotNull { it.lhv as? EtsLocal }
90+
.distinct()
91+
92+
assertEquals(method.locals, listOf(
93+
EtsLocal("i", EtsUnknownType),
94+
EtsLocal("_tmp0", EtsUnknownType),
95+
))
8396
}
8497
}

0 commit comments

Comments
 (0)