Skip to content
Merged
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
14 changes: 11 additions & 3 deletions jacodb-ets/src/main/kotlin/org/jacodb/ets/dto/Convert.kt
Original file line number Diff line number Diff line change
Expand Up @@ -143,15 +143,22 @@ class EtsMethodBuilder(
typeParameters: List<EtsType> = emptyList(),
modifiers: EtsModifiers = EtsModifiers.EMPTY,
decorators: List<EtsDecorator> = emptyList(),
locals: List<EtsLocal> = emptyList(),
) {
private val method = EtsMethodImpl(signature, typeParameters, modifiers, decorators)
private val locals = locals.toMutableList()

private val method = EtsMethodImpl(signature, typeParameters, modifiers, decorators).also {
it.body.locals = this.locals
}

private lateinit var currentStmts: MutableList<EtsStmt>

private var freeTempLocal: Int = 0

private fun newTempLocal(): EtsLocal {
return EtsLocal("_tmp${freeTempLocal++}")
val local = EtsLocal("_tmp${freeTempLocal++}")
this@EtsMethodBuilder.locals += local
return local
}

private fun loc(): EtsStmtLocation {
Expand All @@ -163,7 +170,7 @@ class EtsMethodBuilder(
fun build(cfgDto: CfgDto): EtsMethod {
require(!built) { "Method has already been built" }
val cfg = cfgDto.toEtsCfg()
method._cfg = cfg
method.body.cfg = cfg
built = true
return method
}
Expand Down Expand Up @@ -682,6 +689,7 @@ fun MethodDto.toEtsMethod(): EtsMethod {
typeParameters = typeParameters,
modifiers = modifiers,
decorators = decorators,
locals = body.locals.map { it.toEtsLocal() },
)
return builder.build(body.cfg)
} else {
Expand Down
25 changes: 20 additions & 5 deletions jacodb-ets/src/main/kotlin/org/jacodb/ets/model/Method.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import org.jacodb.api.common.CommonMethod
interface EtsMethod : Base, CommonMethod {
val signature: EtsMethodSignature
val typeParameters: List<EtsType>
val cfg: EtsBlockCfg
val body: EtsMethodBody

val enclosingClass: EtsClass?

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

val cfg: EtsBlockCfg
get() = body.cfg

val locals: List<EtsLocal>
get() = body.locals

override fun flowGraph(): EtsBytecodeGraph<EtsStmt> {
return cfg
}
}

class EtsMethodBody(
var cfg: EtsBlockCfg = EtsBlockCfg.EMPTY,
var locals: List<EtsLocal> = emptyList(),
)

class EtsMethodImpl(
override val signature: EtsMethodSignature,
override val typeParameters: List<EtsType> = emptyList(),
override val modifiers: EtsModifiers = EtsModifiers.EMPTY,
override val decorators: List<EtsDecorator> = emptyList(),
) : EtsMethod {
var _cfg: EtsBlockCfg? = null

override val cfg: EtsBlockCfg
get() = _cfg ?: EtsBlockCfg.EMPTY
override val body: EtsMethodBody = EtsMethodBody()

@Deprecated("Use body.cfg instead", ReplaceWith("body.cfg"))
var _cfg: EtsBlockCfg
get() = body.cfg
set(value) {
body.cfg = value
}

override var enclosingClass: EtsClass? = null

Expand Down
15 changes: 14 additions & 1 deletion jacodb-ets/src/test/kotlin/org/jacodb/ets/test/EtsCfgDslTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ import org.jacodb.ets.dsl.param
import org.jacodb.ets.dsl.program
import org.jacodb.ets.dsl.toBlockCfg
import org.jacodb.ets.dsl.toDot
import org.jacodb.ets.model.EtsAssignStmt
import org.jacodb.ets.model.EtsClassSignature
import org.jacodb.ets.model.EtsFileSignature
import org.jacodb.ets.model.EtsLocal
import org.jacodb.ets.model.EtsMethodImpl
import org.jacodb.ets.model.EtsMethodParameter
import org.jacodb.ets.model.EtsMethodSignature
Expand All @@ -35,6 +37,8 @@ import org.jacodb.ets.utils.linearize
import org.jacodb.ets.utils.toDot
import org.jacodb.ets.utils.toEtsBlockCfg
import org.junit.jupiter.api.Test
import kotlin.test.assertContentEquals
import kotlin.test.assertEquals

class EtsCfgDslTest {
@Test
Expand Down Expand Up @@ -79,6 +83,15 @@ class EtsCfgDslTest {
val etsCfg = etsBlockCfg.linearize()
println("etsCfg:\n${etsCfg.toDot()}")

method._cfg = etsBlockCfg
method.body.cfg = etsBlockCfg
method.body.locals = etsBlockCfg.stmts
.filterIsInstance<EtsAssignStmt>()
.mapNotNull { it.lhv as? EtsLocal }
.distinct()

assertEquals(method.locals, listOf(
EtsLocal("i", EtsUnknownType),
EtsLocal("_tmp0", EtsUnknownType),
))
}
}