FIR: thread control flow through anonymous object init blocks
^KT-39646 Fixed
This commit is contained in:
@@ -156,15 +156,21 @@ interface ExitNodeMarker
|
||||
|
||||
// ----------------------------------- EnterNode for declaration with CFG -----------------------------------
|
||||
|
||||
sealed class CFGNodeWithCfgOwner<out E : FirControlFlowGraphOwner>(owner: ControlFlowGraph, level: Int, id: Int) : CFGNode<E>(owner, level, id) {
|
||||
sealed class CFGNodeWithSubgraphs<out E : FirElement>(owner: ControlFlowGraph, level: Int, id: Int) : CFGNode<E>(owner, level, id) {
|
||||
private val _subGraphs = mutableListOf<ControlFlowGraph>()
|
||||
|
||||
fun addSubGraph(graph: ControlFlowGraph){
|
||||
_subGraphs += graph
|
||||
}
|
||||
|
||||
val subGraphs: List<ControlFlowGraph> by lazy {
|
||||
_subGraphs.also { it.addIfNotNull(fir.controlFlowGraphReference?.controlFlowGraph) }
|
||||
open val subGraphs: List<ControlFlowGraph>
|
||||
get() = _subGraphs
|
||||
}
|
||||
|
||||
sealed class CFGNodeWithCfgOwner<out E : FirControlFlowGraphOwner>(owner: ControlFlowGraph, level: Int, id: Int) : CFGNodeWithSubgraphs<E>(owner, level, id) {
|
||||
override val subGraphs: List<ControlFlowGraph> by lazy {
|
||||
fir.controlFlowGraphReference?.controlFlowGraph?.run(::addSubGraph)
|
||||
super.subGraphs
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,7 +277,13 @@ class LocalClassExitNode(owner: ControlFlowGraph, override val fir: FirRegularCl
|
||||
}
|
||||
}
|
||||
|
||||
class AnonymousObjectExitNode(owner: ControlFlowGraph, override val fir: FirAnonymousObject, level: Int, id: Int) : CFGNodeWithCfgOwner<FirAnonymousObject>(owner, level, id) {
|
||||
class AnonymousObjectEnterNode(owner: ControlFlowGraph, override val fir: FirAnonymousObject, level: Int, id: Int) : CFGNodeWithCfgOwner<FirAnonymousObject>(owner, level, id) {
|
||||
override fun <R, D> accept(visitor: ControlFlowGraphVisitor<R, D>, data: D): R {
|
||||
return visitor.visitAnonymousObjectEnterNode(this, data)
|
||||
}
|
||||
}
|
||||
|
||||
class AnonymousObjectExitNode(owner: ControlFlowGraph, override val fir: FirAnonymousObject, level: Int, id: Int) : CFGNodeWithSubgraphs<FirAnonymousObject>(owner, level, id) {
|
||||
override fun <R, D> accept(visitor: ControlFlowGraphVisitor<R, D>, data: D): R {
|
||||
return visitor.visitAnonymousObjectExitNode(this, data)
|
||||
}
|
||||
|
||||
@@ -111,6 +111,7 @@ fun CFGNode<*>.render(): String =
|
||||
is ClassEnterNode -> "Enter class ${owner.name}"
|
||||
is ClassExitNode -> "Exit class ${owner.name}"
|
||||
is LocalClassExitNode -> "Exit local class ${owner.name}"
|
||||
is AnonymousObjectEnterNode -> "Enter anonymous object"
|
||||
is AnonymousObjectExitNode -> "Exit anonymous object"
|
||||
is AnonymousObjectExpressionExitNode -> "Exit anonymous object expression"
|
||||
|
||||
|
||||
+4
@@ -52,6 +52,10 @@ abstract class ControlFlowGraphVisitor<out R, in D> {
|
||||
|
||||
// ----------------------------------- Classes -----------------------------------
|
||||
|
||||
open fun visitAnonymousObjectEnterNode(node: AnonymousObjectEnterNode, data: D): R {
|
||||
return visitNode(node, data)
|
||||
}
|
||||
|
||||
open fun visitAnonymousObjectExitNode(node: AnonymousObjectExitNode, data: D): R {
|
||||
return visitNode(node, data)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user