FIR CFA: add a hack for enum classes and LL API

No clue what's going on there.
This commit is contained in:
pyos
2022-12-11 21:58:32 +01:00
committed by Dmitriy Novozhilov
parent 377b7bdf5e
commit dca6caaafa
@@ -434,15 +434,25 @@ class ControlFlowGraphBuilder {
}
fun exitClass(): Pair<ClassExitNode?, ControlFlowGraph>? {
assert(currentGraph.kind == ControlFlowGraph.Kind.Class)
if (currentGraph.declaration == null) {
graphs.pop().also { assert(it.kind == ControlFlowGraph.Kind.Class) }
graphs.pop()
return null
}
// Members of a class can be visited in any order, so data flow between them is unordered,
// and we have to recreate the control flow after the fact.
assert(currentGraph.kind == ControlFlowGraph.Kind.Class)
val klass = currentGraph.declaration as FirClass
val enterNode = lastNodes.pop() as ClassEnterNode
val exitNode = currentGraph.exitNode as ClassExitNode
val klass = enterNode.fir
if ((klass as FirControlFlowGraphOwner).controlFlowGraphReference != null) {
// TODO: IDE LL API sometimes attempts to analyze a enum class while already analyzing it, causing
// this graph to be built twice (or more). Not sure what this means. Nothing good, probably.
// In any case, attempting to add more edges to subgraphs will be fatal.
graphs.pop()
return null
}
val calledInPlace = mutableListOf<ControlFlowGraph>()
val calledLater = mutableListOf<ControlFlowGraph>()
klass.forEachGraphOwner { member, isInPlace ->
@@ -450,9 +460,6 @@ class ControlFlowGraphBuilder {
if (isInPlace) calledInPlace.add(graph) else calledLater.add(graph)
}
val enterNode = lastNodes.pop() as ClassEnterNode
val exitNode = currentGraph.exitNode as ClassExitNode
// Classes are not initialized in place so no point in merging data flow - it will not be used.
val mergeDataFlow = klass is FirAnonymousObject && klass.classKind != ClassKind.ENUM_ENTRY
val exitKind = if (mergeDataFlow) EdgeKind.Forward else EdgeKind.CfgForward