diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt index 2f436204351..84389e65c5b 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt @@ -122,6 +122,10 @@ abstract class FirDataFlowAnalyzer( return graphBuilder.returnExpressionsOfAnonymousFunction(function) } + fun dropSubgraphFromCall(call: FirFunctionCall) { + graphBuilder.dropSubgraphFromCall(call) + } + // ----------------------------------- Named function ----------------------------------- fun enterFunction(function: FirFunction<*>) { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraph.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraph.kt index c5d064b3f14..6ff68403775 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraph.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraph.kt @@ -42,6 +42,15 @@ class ControlFlowGraph(val declaration: FirDeclaration?, val name: String, val k _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 { Function, ClassInitializer, TopLevel } @@ -67,6 +76,24 @@ sealed class CFGNode(val owner: ControlFlowGraph, val level: 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 { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphBuilder.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphBuilder.kt index 300928a2005..8b9dd8a2975 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphBuilder.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphBuilder.kt @@ -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.FirFunctionSymbol import org.jetbrains.kotlin.fir.types.isNothing +import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitorVoid import kotlin.random.Random class ControlFlowGraphBuilder { @@ -921,4 +922,24 @@ class ControlFlowGraphBuilder { exitsOfAnonymousFunctions.clear() exitsFromCompletedPostponedAnonymousFunctions.clear() } + + fun dropSubgraphFromCall(call: FirFunctionCall) { + val graphs = mutableListOf() + 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) + } + } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt index ae7fce82331..ae3a403cf75 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt @@ -185,6 +185,7 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) } } + (delegateProvider as? FirFunctionCall)?.let { dataFlowAnalyzer.dropSubgraphFromCall(it) } return wrappedDelegateExpression.expression.transform(transformer, ResolutionMode.ContextDependent) } finally { dataFlowAnalyzer.exitDelegateExpression()