FIR DFA: split flow for postponed lambdas from a single node

This removes the need for hacks around the order in which function
call arguments are visited, fixes called-in-place lambda arguments
for augmented assignment operators, and makes CFG dumps a bit prettier.
This commit is contained in:
pyos
2022-11-24 18:01:32 +01:00
committed by teamcity
parent 402ea98e02
commit 664a70ec13
16 changed files with 819 additions and 910 deletions
@@ -243,9 +243,10 @@ class ExitDefaultArgumentsNode(owner: ControlFlowGraph, override val fir: FirVal
// ----------------------------------- Anonymous function -----------------------------------
class PostponedLambdaEnterNode(owner: ControlFlowGraph, override val fir: FirAnonymousFunctionExpression, level: Int, id: Int) : CFGNodeWithSubgraphs<FirAnonymousFunctionExpression>(owner, level, id) {
class SplitPostponedLambdasNode(owner: ControlFlowGraph, override val fir: FirStatement, val lambdas: List<FirAnonymousFunction>, level: Int, id: Int)
: CFGNodeWithSubgraphs<FirStatement>(owner, level, id) {
override fun <R, D> accept(visitor: ControlFlowGraphVisitor<R, D>, data: D): R {
return visitor.visitPostponedLambdaEnterNode(this, data)
return visitor.visitSplitPostponedLambdasNode(this, data)
}
}
@@ -261,9 +262,9 @@ class MergePostponedLambdaExitsNode(owner: ControlFlowGraph, override val fir: F
}
}
class AnonymousFunctionExpressionExitNode(owner: ControlFlowGraph, override val fir: FirAnonymousFunctionExpression, level: Int, id: Int) : CFGNode<FirAnonymousFunctionExpression>(owner, level, id) {
class AnonymousFunctionExpressionNode(owner: ControlFlowGraph, override val fir: FirAnonymousFunctionExpression, level: Int, id: Int) : CFGNodeWithSubgraphs<FirAnonymousFunctionExpression>(owner, level, id) {
override fun <R, D> accept(visitor: ControlFlowGraphVisitor<R, D>, data: D): R {
return visitor.visitAnonymousFunctionExpressionExitNode(this, data)
return visitor.visitAnonymousFunctionExpressionNode(this, data)
}
}
@@ -98,12 +98,10 @@ fun CFGNode<*>.render(): String =
is WhenSubjectExpressionExitNode -> "Exit ${'$'}subj"
is PostponedLambdaEnterNode -> "Postponed enter to lambda"
is SplitPostponedLambdasNode -> "Postponed enter to lambda"
is PostponedLambdaExitNode -> "Postponed exit from lambda"
is AnonymousFunctionExpressionExitNode -> "Exit anonymous function expression"
is MergePostponedLambdaExitsNode -> "Merge postponed lambda exits"
is AnonymousFunctionExpressionNode -> "Exit anonymous function expression"
is ClassEnterNode -> "Enter class ${owner.name}"
is ClassExitNode -> "Exit class ${owner.name}"
@@ -36,7 +36,7 @@ abstract class ControlFlowGraphVisitor<out R, in D> {
// ----------------------------------- Anonymous function -----------------------------------
open fun visitPostponedLambdaEnterNode(node: PostponedLambdaEnterNode, data: D): R {
open fun visitSplitPostponedLambdasNode(node: SplitPostponedLambdasNode, data: D): R {
return visitNode(node, data)
}
@@ -48,7 +48,7 @@ abstract class ControlFlowGraphVisitor<out R, in D> {
return visitNode(node, data)
}
open fun visitAnonymousFunctionExpressionExitNode(node: AnonymousFunctionExpressionExitNode, data: D): R {
open fun visitAnonymousFunctionExpressionNode(node: AnonymousFunctionExpressionNode, data: D): R {
return visitNode(node, data)
}
@@ -20,9 +20,13 @@ abstract class ControlFlowGraphVisitorVoid : ControlFlowGraphVisitor<Unit, Nothi
visitNode(node)
}
open fun visitLocalFunctionDeclarationNode(node: LocalFunctionDeclarationNode) {
visitNode(node)
}
// ----------------------------------- Anonymous function -----------------------------------
open fun visitPostponedLambdaEnterNode(node: PostponedLambdaEnterNode) {
open fun visitSplitPostponedLambdasNode(node: SplitPostponedLambdasNode) {
visitNode(node)
}
@@ -34,6 +38,10 @@ abstract class ControlFlowGraphVisitorVoid : ControlFlowGraphVisitor<Unit, Nothi
visitNode(node)
}
open fun visitAnonymousFunctionExpressionNode(node: AnonymousFunctionExpressionNode) {
visitNode(node)
}
// ----------------------------------- Anonymous object -----------------------------------
open fun visitAnonymousObjectExitNode(node: AnonymousObjectExitNode) {
@@ -313,10 +321,14 @@ abstract class ControlFlowGraphVisitorVoid : ControlFlowGraphVisitor<Unit, Nothi
visitFunctionExitNode(node)
}
final override fun visitLocalFunctionDeclarationNode(node: LocalFunctionDeclarationNode, data: Nothing?) {
visitLocalFunctionDeclarationNode(node)
}
// ----------------------------------- Anonymous function -----------------------------------
final override fun visitPostponedLambdaEnterNode(node: PostponedLambdaEnterNode, data: Nothing?) {
visitPostponedLambdaEnterNode(node)
final override fun visitSplitPostponedLambdasNode(node: SplitPostponedLambdasNode, data: Nothing?) {
visitSplitPostponedLambdasNode(node)
}
final override fun visitPostponedLambdaExitNode(node: PostponedLambdaExitNode, data: Nothing?) {
@@ -327,6 +339,10 @@ abstract class ControlFlowGraphVisitorVoid : ControlFlowGraphVisitor<Unit, Nothi
visitMergePostponedLambdaExitsNode(node)
}
final override fun visitAnonymousFunctionExpressionNode(node: AnonymousFunctionExpressionNode, data: Nothing?) {
visitAnonymousFunctionExpressionNode(node)
}
// ----------------------------------- Anonymous object -----------------------------------
final override fun visitAnonymousObjectExitNode(node: AnonymousObjectExitNode, data: Nothing?) {