[FIR] Drop subgraphs of lambda arguments of delegate calls
This commit is contained in:
@@ -122,6 +122,10 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
|
|||||||
return graphBuilder.returnExpressionsOfAnonymousFunction(function)
|
return graphBuilder.returnExpressionsOfAnonymousFunction(function)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun dropSubgraphFromCall(call: FirFunctionCall) {
|
||||||
|
graphBuilder.dropSubgraphFromCall(call)
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------- Named function -----------------------------------
|
// ----------------------------------- Named function -----------------------------------
|
||||||
|
|
||||||
fun enterFunction(function: FirFunction<*>) {
|
fun enterFunction(function: FirFunction<*>) {
|
||||||
|
|||||||
@@ -42,6 +42,15 @@ class ControlFlowGraph(val declaration: FirDeclaration?, val name: String, val k
|
|||||||
_subGraphs += graph
|
_subGraphs += graph
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun removeSubGraph(graph: ControlFlowGraph) {
|
||||||
|
assert(graph.owner == this)
|
||||||
|
_subGraphs.remove(graph)
|
||||||
|
graph.owner = null
|
||||||
|
|
||||||
|
CFGNode.removeAllIncomingEdges(graph.enterNode)
|
||||||
|
CFGNode.removeAllOutgoingEdges(graph.exitNode)
|
||||||
|
}
|
||||||
|
|
||||||
enum class Kind {
|
enum class Kind {
|
||||||
Function, ClassInitializer, TopLevel
|
Function, ClassInitializer, TopLevel
|
||||||
}
|
}
|
||||||
@@ -67,6 +76,24 @@ sealed class CFGNode<out E : FirElement>(val owner: ControlFlowGraph, val level:
|
|||||||
to.isDead = true
|
to.isDead = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun removeAllIncomingEdges(to: CFGNode<*>) {
|
||||||
|
for (from in to._previousNodes) {
|
||||||
|
from._followingNodes.remove(to)
|
||||||
|
from._outgoingEdges.remove(to)
|
||||||
|
to._incomingEdges.remove(from)
|
||||||
|
}
|
||||||
|
to._previousNodes.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun removeAllOutgoingEdges(from: CFGNode<*>) {
|
||||||
|
for (to in from._followingNodes) {
|
||||||
|
to._previousNodes.remove(from)
|
||||||
|
from._outgoingEdges.remove(to)
|
||||||
|
to._incomingEdges.remove(from)
|
||||||
|
}
|
||||||
|
from._followingNodes.clear()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
|||||||
+21
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
|||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.isNothing
|
import org.jetbrains.kotlin.fir.types.isNothing
|
||||||
|
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitorVoid
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
|
|
||||||
class ControlFlowGraphBuilder {
|
class ControlFlowGraphBuilder {
|
||||||
@@ -921,4 +922,24 @@ class ControlFlowGraphBuilder {
|
|||||||
exitsOfAnonymousFunctions.clear()
|
exitsOfAnonymousFunctions.clear()
|
||||||
exitsFromCompletedPostponedAnonymousFunctions.clear()
|
exitsFromCompletedPostponedAnonymousFunctions.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun dropSubgraphFromCall(call: FirFunctionCall) {
|
||||||
|
val graphs = mutableListOf<ControlFlowGraph>()
|
||||||
|
call.acceptChildren(object : FirDefaultVisitorVoid() {
|
||||||
|
override fun visitElement(element: FirElement) {
|
||||||
|
element.acceptChildren(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitAnonymousFunction(anonymousFunction: FirAnonymousFunction) {
|
||||||
|
anonymousFunction.controlFlowGraphReference.controlFlowGraph?.let {
|
||||||
|
graphs += it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, null)
|
||||||
|
|
||||||
|
val currentGraph = graph
|
||||||
|
for (graph in graphs) {
|
||||||
|
currentGraph.removeSubGraph(graph)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -185,6 +185,7 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
(delegateProvider as? FirFunctionCall)?.let { dataFlowAnalyzer.dropSubgraphFromCall(it) }
|
||||||
return wrappedDelegateExpression.expression.transform(transformer, ResolutionMode.ContextDependent)
|
return wrappedDelegateExpression.expression.transform(transformer, ResolutionMode.ContextDependent)
|
||||||
} finally {
|
} finally {
|
||||||
dataFlowAnalyzer.exitDelegateExpression()
|
dataFlowAnalyzer.exitDelegateExpression()
|
||||||
|
|||||||
Reference in New Issue
Block a user