FIR checker: deprecate path-insensitive data collection
This commit is contained in:
committed by
Mikhail Glukhikh
parent
168503573a
commit
762e315ce3
@@ -112,7 +112,7 @@ class PropertyInitializationInfoCollector(private val localProperties: Set<FirPr
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getData(graph: ControlFlowGraph) =
|
fun getData(graph: ControlFlowGraph) =
|
||||||
graph.collectPathAwareDataForNode(
|
graph.collectDataForNode(
|
||||||
TraverseDirection.Forward,
|
TraverseDirection.Forward,
|
||||||
PathAwarePropertyInitializationInfo.EMPTY,
|
PathAwarePropertyInitializationInfo.EMPTY,
|
||||||
this
|
this
|
||||||
|
|||||||
@@ -31,14 +31,12 @@ fun ControlFlowGraph.traverse(
|
|||||||
traverse(direction, visitor, null)
|
traverse(direction, visitor, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------- Path-sensitive data collection -----------------------
|
||||||
|
|
||||||
// --------------------- Path-insensitive data collection ----------------------
|
|
||||||
|
|
||||||
// TODO: Deprecate and make all existing checkers path-sensitive
|
|
||||||
fun <I : ControlFlowInfo<I, K, V>, K : Any, V : Any> ControlFlowGraph.collectDataForNode(
|
fun <I : ControlFlowInfo<I, K, V>, K : Any, V : Any> ControlFlowGraph.collectDataForNode(
|
||||||
direction: TraverseDirection,
|
direction: TraverseDirection,
|
||||||
initialInfo: I,
|
initialInfo: I,
|
||||||
visitor: ControlFlowGraphVisitor<I, Collection<I>>
|
visitor: ControlFlowGraphVisitor<I, Collection<Pair<EdgeLabel, I>>>
|
||||||
): Map<CFGNode<*>, I> {
|
): Map<CFGNode<*>, I> {
|
||||||
val nodeMap = LinkedHashMap<CFGNode<*>, I>()
|
val nodeMap = LinkedHashMap<CFGNode<*>, I>()
|
||||||
val startNode = getEnterNode(direction)
|
val startNode = getEnterNode(direction)
|
||||||
@@ -53,56 +51,6 @@ fun <I : ControlFlowInfo<I, K, V>, K : Any, V : Any> ControlFlowGraph.collectDat
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun <I : ControlFlowInfo<I, K, V>, K : Any, V : Any> ControlFlowGraph.collectDataForNodeInternal(
|
private fun <I : ControlFlowInfo<I, K, V>, K : Any, V : Any> ControlFlowGraph.collectDataForNodeInternal(
|
||||||
direction: TraverseDirection,
|
|
||||||
initialInfo: I,
|
|
||||||
visitor: ControlFlowGraphVisitor<I, Collection<I>>,
|
|
||||||
nodeMap: MutableMap<CFGNode<*>, I>,
|
|
||||||
changed: MutableMap<CFGNode<*>, Boolean>
|
|
||||||
) {
|
|
||||||
val nodes = getNodesInOrder(direction)
|
|
||||||
for (node in nodes) {
|
|
||||||
if (direction == TraverseDirection.Backward && node is CFGNodeWithCfgOwner<*>) {
|
|
||||||
node.subGraphs.forEach { it.collectDataForNodeInternal(direction, initialInfo, visitor, nodeMap, changed) }
|
|
||||||
}
|
|
||||||
val previousNodes = when (direction) {
|
|
||||||
TraverseDirection.Forward -> node.previousCfgNodes
|
|
||||||
TraverseDirection.Backward -> node.followingCfgNodes
|
|
||||||
}
|
|
||||||
val previousData = previousNodes.mapNotNull { nodeMap[it] }
|
|
||||||
val data = nodeMap[node]
|
|
||||||
val newData = node.accept(visitor, previousData)
|
|
||||||
val hasChanged = newData != data
|
|
||||||
changed[node] = hasChanged
|
|
||||||
if (hasChanged) {
|
|
||||||
nodeMap[node] = newData
|
|
||||||
}
|
|
||||||
if (direction == TraverseDirection.Forward && node is CFGNodeWithCfgOwner<*>) {
|
|
||||||
node.subGraphs.forEach { it.collectDataForNodeInternal(direction, initialInfo, visitor, nodeMap, changed) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------- Path-sensitive data collection -----------------------
|
|
||||||
|
|
||||||
// TODO: Once migration is done, get rid of "PathAware" from util names
|
|
||||||
fun <I : ControlFlowInfo<I, K, V>, K : Any, V : Any> ControlFlowGraph.collectPathAwareDataForNode(
|
|
||||||
direction: TraverseDirection,
|
|
||||||
initialInfo: I,
|
|
||||||
visitor: ControlFlowGraphVisitor<I, Collection<Pair<EdgeLabel, I>>>
|
|
||||||
): Map<CFGNode<*>, I> {
|
|
||||||
val nodeMap = LinkedHashMap<CFGNode<*>, I>()
|
|
||||||
val startNode = getEnterNode(direction)
|
|
||||||
nodeMap[startNode] = initialInfo
|
|
||||||
|
|
||||||
val changed = mutableMapOf<CFGNode<*>, Boolean>()
|
|
||||||
do {
|
|
||||||
collectPathAwareDataForNodeInternal(direction, initialInfo, visitor, nodeMap, changed)
|
|
||||||
} while (changed.any { it.value })
|
|
||||||
|
|
||||||
return nodeMap
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun <I : ControlFlowInfo<I, K, V>, K : Any, V : Any> ControlFlowGraph.collectPathAwareDataForNodeInternal(
|
|
||||||
direction: TraverseDirection,
|
direction: TraverseDirection,
|
||||||
initialInfo: I,
|
initialInfo: I,
|
||||||
visitor: ControlFlowGraphVisitor<I, Collection<Pair<EdgeLabel, I>>>,
|
visitor: ControlFlowGraphVisitor<I, Collection<Pair<EdgeLabel, I>>>,
|
||||||
@@ -112,7 +60,7 @@ private fun <I : ControlFlowInfo<I, K, V>, K : Any, V : Any> ControlFlowGraph.co
|
|||||||
val nodes = getNodesInOrder(direction)
|
val nodes = getNodesInOrder(direction)
|
||||||
for (node in nodes) {
|
for (node in nodes) {
|
||||||
if (direction == TraverseDirection.Backward && node is CFGNodeWithCfgOwner<*>) {
|
if (direction == TraverseDirection.Backward && node is CFGNodeWithCfgOwner<*>) {
|
||||||
node.subGraphs.forEach { it.collectPathAwareDataForNodeInternal(direction, initialInfo, visitor, nodeMap, changed) }
|
node.subGraphs.forEach { it.collectDataForNodeInternal(direction, initialInfo, visitor, nodeMap, changed) }
|
||||||
}
|
}
|
||||||
val previousNodes = when (direction) {
|
val previousNodes = when (direction) {
|
||||||
TraverseDirection.Forward -> node.previousCfgNodes
|
TraverseDirection.Forward -> node.previousCfgNodes
|
||||||
@@ -136,7 +84,7 @@ private fun <I : ControlFlowInfo<I, K, V>, K : Any, V : Any> ControlFlowGraph.co
|
|||||||
nodeMap[node] = newData
|
nodeMap[node] = newData
|
||||||
}
|
}
|
||||||
if (direction == TraverseDirection.Forward && node is CFGNodeWithCfgOwner<*>) {
|
if (direction == TraverseDirection.Forward && node is CFGNodeWithCfgOwner<*>) {
|
||||||
node.subGraphs.forEach { it.collectPathAwareDataForNodeInternal(direction, initialInfo, visitor, nodeMap, changed) }
|
node.subGraphs.forEach { it.collectDataForNodeInternal(direction, initialInfo, visitor, nodeMap, changed) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -80,7 +80,7 @@ object FirCallsEffectAnalyzer : FirControlFlowChecker() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val invocationData = graph.collectPathAwareDataForNode(
|
val invocationData = graph.collectDataForNode(
|
||||||
TraverseDirection.Forward,
|
TraverseDirection.Forward,
|
||||||
PathAwareLambdaInvocationInfo.EMPTY,
|
PathAwareLambdaInvocationInfo.EMPTY,
|
||||||
InvocationDataCollector(functionalTypeEffects.keys.filterTo(mutableSetOf()) { it !in leakedSymbols })
|
InvocationDataCollector(functionalTypeEffects.keys.filterTo(mutableSetOf()) { it !in leakedSymbols })
|
||||||
|
|||||||
+1
-1
@@ -151,7 +151,7 @@ object UnusedChecker : FirControlFlowChecker() {
|
|||||||
private val localProperties: Set<FirPropertySymbol>
|
private val localProperties: Set<FirPropertySymbol>
|
||||||
) : ControlFlowGraphVisitor<PathAwareVariableStatusInfo, Collection<Pair<EdgeLabel, PathAwareVariableStatusInfo>>>() {
|
) : ControlFlowGraphVisitor<PathAwareVariableStatusInfo, Collection<Pair<EdgeLabel, PathAwareVariableStatusInfo>>>() {
|
||||||
fun getData(graph: ControlFlowGraph): Map<CFGNode<*>, PathAwareVariableStatusInfo> {
|
fun getData(graph: ControlFlowGraph): Map<CFGNode<*>, PathAwareVariableStatusInfo> {
|
||||||
return graph.collectPathAwareDataForNode(TraverseDirection.Backward, PathAwareVariableStatusInfo.EMPTY, this)
|
return graph.collectDataForNode(TraverseDirection.Backward, PathAwareVariableStatusInfo.EMPTY, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitNode(
|
override fun visitNode(
|
||||||
|
|||||||
Reference in New Issue
Block a user