[FIR] Add different states for CFG and some assertions for graph modification
This commit is contained in:
@@ -3,6 +3,8 @@
|
|||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@file:Suppress("Reformat")
|
||||||
|
|
||||||
package org.jetbrains.kotlin.fir.resolve.dfa.cfg
|
package org.jetbrains.kotlin.fir.resolve.dfa.cfg
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.FirElement
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
|
|||||||
+21
-3
@@ -3,8 +3,6 @@
|
|||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@file:Suppress("Reformat")
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.fir.resolve.dfa.cfg
|
package org.jetbrains.kotlin.fir.resolve.dfa.cfg
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||||
@@ -15,20 +13,29 @@ class ControlFlowGraph(val declaration: FirDeclaration?, val name: String, val k
|
|||||||
val nodes: List<CFGNode<*>> get() = _nodes
|
val nodes: List<CFGNode<*>> get() = _nodes
|
||||||
|
|
||||||
internal fun addNode(node: CFGNode<*>) {
|
internal fun addNode(node: CFGNode<*>) {
|
||||||
|
assertState(State.Building)
|
||||||
_nodes += node
|
_nodes += node
|
||||||
}
|
}
|
||||||
|
|
||||||
lateinit var enterNode: CFGNode<*>
|
lateinit var enterNode: CFGNode<*>
|
||||||
internal set
|
internal set
|
||||||
|
|
||||||
lateinit var exitNode: CFGNode<*>
|
lateinit var exitNode: CFGNode<*>
|
||||||
internal set
|
internal set
|
||||||
|
|
||||||
var owner: ControlFlowGraph? = null
|
var owner: ControlFlowGraph? = null
|
||||||
private set
|
private set
|
||||||
|
|
||||||
|
var state: State = State.Building
|
||||||
|
private set
|
||||||
|
|
||||||
private val _subGraphs: MutableList<ControlFlowGraph> = mutableListOf()
|
private val _subGraphs: MutableList<ControlFlowGraph> = mutableListOf()
|
||||||
val subGraphs: List<ControlFlowGraph> get() = _subGraphs
|
val subGraphs: List<ControlFlowGraph> get() = _subGraphs
|
||||||
|
|
||||||
|
internal fun complete() {
|
||||||
|
assertState(State.Building)
|
||||||
|
state = State.Completed
|
||||||
|
}
|
||||||
|
|
||||||
internal fun addSubGraph(graph: ControlFlowGraph) {
|
internal fun addSubGraph(graph: ControlFlowGraph) {
|
||||||
assert(graph.owner == null) {
|
assert(graph.owner == null) {
|
||||||
"SubGraph already has owner"
|
"SubGraph already has owner"
|
||||||
@@ -46,6 +53,17 @@ class ControlFlowGraph(val declaration: FirDeclaration?, val name: String, val k
|
|||||||
CFGNode.removeAllOutgoingEdges(graph.exitNode)
|
CFGNode.removeAllOutgoingEdges(graph.exitNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun assertState(state: State) {
|
||||||
|
assert(this.state == state) {
|
||||||
|
"This action can not be performed at $this state"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class State {
|
||||||
|
Building,
|
||||||
|
Completed;
|
||||||
|
}
|
||||||
|
|
||||||
enum class Kind {
|
enum class Kind {
|
||||||
Function, ClassInitializer, TopLevel
|
Function, ClassInitializer, TopLevel
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-3
@@ -173,6 +173,7 @@ class ControlFlowGraphBuilder {
|
|||||||
exitNode.updateDeadStatus()
|
exitNode.updateDeadStatus()
|
||||||
val graph = graphs.pop().also { graph ->
|
val graph = graphs.pop().also { graph ->
|
||||||
exitsFromCompletedPostponedAnonymousFunctions.removeAll { it.owner == graph }
|
exitsFromCompletedPostponedAnonymousFunctions.removeAll { it.owner == graph }
|
||||||
|
graph.complete()
|
||||||
}
|
}
|
||||||
val previousGraph = parentGraphForAnonymousFunctions.remove(function.symbol) ?: graphs.top()
|
val previousGraph = parentGraphForAnonymousFunctions.remove(function.symbol) ?: graphs.top()
|
||||||
if (previousGraph.kind == ControlFlowGraph.Kind.Function) {
|
if (previousGraph.kind == ControlFlowGraph.Kind.Function) {
|
||||||
@@ -252,7 +253,7 @@ class ControlFlowGraphBuilder {
|
|||||||
}
|
}
|
||||||
val exitNode = createClassExitNode(klass)
|
val exitNode = createClassExitNode(klass)
|
||||||
addEdge(node, exitNode, preferredKind = EdgeKind.Cfg)
|
addEdge(node, exitNode, preferredKind = EdgeKind.Cfg)
|
||||||
return graphs.pop()
|
return graphs.pop().also { it.complete() }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun prepareForLocalClassMembers(members: Collection<FirSymbolOwner<*>>) {
|
fun prepareForLocalClassMembers(members: Collection<FirSymbolOwner<*>>) {
|
||||||
@@ -361,7 +362,7 @@ class ControlFlowGraphBuilder {
|
|||||||
levelCounter--
|
levelCounter--
|
||||||
exitNodes.pop()
|
exitNodes.pop()
|
||||||
lexicalScopes.pop()
|
lexicalScopes.pop()
|
||||||
return topLevelVariableExitNode to graphs.pop()
|
return topLevelVariableExitNode to graphs.pop().also { it.complete() }
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------- Delegate -----------------------------------
|
// ----------------------------------- Delegate -----------------------------------
|
||||||
@@ -854,7 +855,7 @@ class ControlFlowGraphBuilder {
|
|||||||
}
|
}
|
||||||
lexicalScopes.pop()
|
lexicalScopes.pop()
|
||||||
exitNodes.pop()
|
exitNodes.pop()
|
||||||
val graph = graphs.pop()
|
val graph = graphs.pop().also { it.complete() }
|
||||||
return exitNode to graph
|
return exitNode to graph
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user