[FIR] Add edge kinds to control flow graph

Another changes:
- Remove useless CFG plain text renderer
- Refactor CFG .dot renderer
- Add checking of consistency control flow graph
This commit is contained in:
Dmitriy Novozhilov
2020-01-29 12:45:43 +03:00
parent 0c2157155d
commit 6716cb0bf3
50 changed files with 13215 additions and 11599 deletions
@@ -709,6 +709,11 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
val flow = node.mergeIncomingFlow().flow val flow = node.mergeIncomingFlow().flow
/*
* TODO: Here we should handle case when one of arguments is dead (e.g. in cases `false && expr` or `true || expr`)
* But since conditions with const are rare it can be delayed
*/
val leftVariable = variableStorage.getOrCreateVariable(binaryLogicExpression.leftOperand) val leftVariable = variableStorage.getOrCreateVariable(binaryLogicExpression.leftOperand)
val rightVariable = variableStorage.getOrCreateVariable(binaryLogicExpression.rightOperand) val rightVariable = variableStorage.getOrCreateVariable(binaryLogicExpression.rightOperand)
val operatorVariable = variableStorage.getOrCreateVariable(binaryLogicExpression) val operatorVariable = variableStorage.getOrCreateVariable(binaryLogicExpression)
@@ -795,7 +800,7 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
val previousFlows = if (node.isDead) val previousFlows = if (node.isDead)
node.previousNodes.map { it.flow } node.previousNodes.map { it.flow }
else else
node.previousNodes.mapNotNull { prev -> prev.takeIf { !it.isDead }?.flow } node.previousNodes.mapNotNull { prev -> prev.takeIf { node.incomingEdges[it] != EdgeKind.Dead }?.flow }
val flow = logicSystem.joinFlow(previousFlows) val flow = logicSystem.joinFlow(previousFlows)
if (updateReceivers) { if (updateReceivers) {
logicSystem.updateAllReceivers(flow) logicSystem.updateAllReceivers(flow)
@@ -24,13 +24,34 @@ class ControlFlowGraph(val name: String, val kind: Kind) {
} }
} }
enum class EdgeKind {
Simple, Dead
}
sealed class CFGNode<out E : FirElement>(val owner: ControlFlowGraph, val level: Int, private val id: Int) { sealed class CFGNode<out E : FirElement>(val owner: ControlFlowGraph, val level: Int, private val id: Int) {
companion object {
fun addEdge(from: CFGNode<*>, to: CFGNode<*>, kind: EdgeKind, propagateDeadness: Boolean) {
from.followingNodes += to
to.previousNodes += from
if (kind != EdgeKind.Simple) {
from.outgoingEdges[to] = kind
to.incomingEdges[from] = kind
}
if (propagateDeadness && kind == EdgeKind.Dead) {
to.isDead = true
}
}
}
init { init {
owner.nodes += this owner.nodes += this
} }
val previousNodes = mutableListOf<CFGNode<*>>() val previousNodes: MutableList<CFGNode<*>> = mutableListOf()
val followingNodes = mutableListOf<CFGNode<*>>() val followingNodes: MutableList<CFGNode<*>> = mutableListOf()
val incomingEdges = mutableMapOf<CFGNode<*>, EdgeKind>().withDefault { EdgeKind.Simple }
val outgoingEdges = mutableMapOf<CFGNode<*>, EdgeKind>().withDefault { EdgeKind.Simple }
val firstPreviousNode: CFGNode<*> get() = previousNodes.first() val firstPreviousNode: CFGNode<*> get() = previousNodes.first()
@@ -47,7 +68,6 @@ sealed class CFGNode<out E : FirElement>(val owner: ControlFlowGraph, val level:
} }
} }
interface EnterNode interface EnterNode
interface ExitNode interface ExitNode
@@ -314,7 +314,7 @@ class ControlFlowGraphBuilder {
val conditionExitNode = createLoopConditionExitNode(loop.condition) val conditionExitNode = createLoopConditionExitNode(loop.condition)
addNewSimpleNode(conditionExitNode) addNewSimpleNode(conditionExitNode)
val conditionConstBooleanValue = conditionExitNode.booleanConstValue val conditionConstBooleanValue = conditionExitNode.booleanConstValue
addEdge(conditionExitNode, loopExitNodes.top(), isDead = conditionConstBooleanValue == true) addEdge(conditionExitNode, loopExitNodes.top(), propagateDeadness = false, isDead = conditionConstBooleanValue == true)
val loopBlockEnterNode = createLoopBlockEnterNode(loop) val loopBlockEnterNode = createLoopBlockEnterNode(loop)
addNewSimpleNode(loopBlockEnterNode, conditionConstBooleanValue == false) addNewSimpleNode(loopBlockEnterNode, conditionConstBooleanValue == false)
levelCounter++ levelCounter++
@@ -431,11 +431,11 @@ class ControlFlowGraphBuilder {
val leftExitNode = createBinaryOrExitLeftOperandNode(binaryLogicExpression).also { val leftExitNode = createBinaryOrExitLeftOperandNode(binaryLogicExpression).also {
addEdge(previousNode, it) addEdge(previousNode, it)
addEdge(it, binaryOrExitNodes.top(), isDead = leftBooleanValue == false) addEdge(it, binaryOrExitNodes.top(), propagateDeadness = false, isDead = leftBooleanValue == false)
} }
val rightExitNode = createBinaryOrEnterRightOperandNode(binaryLogicExpression).also { val rightExitNode = createBinaryOrEnterRightOperandNode(binaryLogicExpression).also {
addEdge(leftExitNode, it, isDead = leftBooleanValue == true) addEdge(leftExitNode, it, propagateDeadness = true, isDead = leftBooleanValue == true)
lastNodes.push(it) lastNodes.push(it)
levelCounter++ levelCounter++
} }
@@ -639,13 +639,14 @@ class ControlFlowGraphBuilder {
fun exitSafeCall(qualifiedAccess: FirQualifiedAccess): ExitSafeCallNode { fun exitSafeCall(qualifiedAccess: FirQualifiedAccess): ExitSafeCallNode {
return exitSafeCallNodes.pop().also { return exitSafeCallNodes.pop().also {
addNewSimpleNode(it) addNewSimpleNode(it)
it.markAsDeadIfNecessary()
} }
} }
// ------------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------------
private fun CFGNode<*>.markAsDeadIfNecessary() { private fun CFGNode<*>.markAsDeadIfNecessary() {
isDead = previousNodes.all { it.isDead } isDead = incomingEdges.size == previousNodes.size && incomingEdges.values.all { it == EdgeKind.Dead }
} }
private fun addNodeThatReturnsNothing(node: CFGNode<*>) { private fun addNodeThatReturnsNothing(node: CFGNode<*>) {
@@ -674,22 +675,9 @@ class ControlFlowGraphBuilder {
return oldNode return oldNode
} }
private fun addDeadEdge(from: CFGNode<*>, to: CFGNode<*>, propagateDeadness: Boolean) {
val stub = createStubNode()
addEdge(from, stub)
addEdge(stub, to, propagateDeadness = propagateDeadness)
}
private fun addEdge(from: CFGNode<*>, to: CFGNode<*>, propagateDeadness: Boolean = true, isDead: Boolean = false) { private fun addEdge(from: CFGNode<*>, to: CFGNode<*>, propagateDeadness: Boolean = true, isDead: Boolean = false) {
if (isDead) { val kind = if (isDead || from.isDead || to.isDead) EdgeKind.Dead else EdgeKind.Simple
addDeadEdge(from, to, propagateDeadness) CFGNode.addEdge(from, to, kind, propagateDeadness)
return
}
if (propagateDeadness && from.isDead) {
to.isDead = true
}
from.followingNodes += to
to.previousNodes += from
} }
private val FirFunction<*>.invocationKind: InvocationKind? private val FirFunction<*>.invocationKind: InvocationKind?
@@ -5,6 +5,7 @@
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.FirRenderer import org.jetbrains.kotlin.fir.FirRenderer
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.expressions.FirDoWhileLoop import org.jetbrains.kotlin.fir.expressions.FirDoWhileLoop
@@ -12,75 +13,125 @@ import org.jetbrains.kotlin.fir.expressions.FirLoop
import org.jetbrains.kotlin.fir.expressions.FirWhileLoop import org.jetbrains.kotlin.fir.expressions.FirWhileLoop
import org.jetbrains.kotlin.fir.expressions.impl.FirElseIfTrueCondition import org.jetbrains.kotlin.fir.expressions.impl.FirElseIfTrueCondition
import org.jetbrains.kotlin.fir.psi import org.jetbrains.kotlin.fir.psi
import org.jetbrains.kotlin.fir.references.FirControlFlowGraphReference
import org.jetbrains.kotlin.fir.render import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.resolve.dfa.FirControlFlowGraphReferenceImpl
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
import org.jetbrains.kotlin.utils.DFS import org.jetbrains.kotlin.utils.DFS
import org.jetbrains.kotlin.utils.Printer
import java.util.*
private const val INDENT = " " class FirControlFlowGraphRenderVisitor(
private const val DEAD = "[DEAD]" builder: StringBuilder,
) : FirVisitorVoid() {
companion object {
private const val EDGE = " -> "
private const val RED = "red"
private const val BLUE = "blue"
private val EDGE_STYLE = EnumMap(
fun List<CFGNode<*>>.indicesMap(): Map<CFGNode<*>, Int> = mapIndexed { i, node -> node to i }.toMap() mapOf(
EdgeKind.Simple to "",
fun ControlFlowGraph.sortNodes(): List<CFGNode<*>> { EdgeKind.Dead to "[style=dotted]",
return DFS.topologicalOrder( )
nodes )
) {
val result = if (it !is WhenBranchConditionExitNode || it.followingNodes.size < 2) {
it.followingNodes
} else {
it.followingNodes.sortedBy { node -> if (node is BlockEnterNode) 1 else 0 }
}
result
}
} }
fun ControlFlowGraph.renderToStringBuilder(builder: StringBuilder) { private val printer = Printer(builder)
val sortedNodes = sortNodes()
val indices = sortedNodes.indicesMap() private var indexOffset = 0
val notVisited = sortedNodes.toMutableSet() private var clusterCounter = 0
val maxLineNumberSize = sortedNodes.size.toString().length
fun List<CFGNode<*>>.renderEdges(nodeIsDead: Boolean): String = map { override fun visitFile(file: FirFile) {
indices.getValue(it) to it.isDead printer
}.sortedBy { it.first }.joinToString(", ") { (index, isDead) -> .println("digraph ${file.name.replace(".", "_")} {")
index.toString() + if (isDead && !nodeIsDead) DEAD else "" .pushIndent()
.println("graph [splines=ortho nodesep=3]")
.println("node [shape=box penwidth=2]")
.println("edge [penwidth=2]")
.println()
visitElement(file)
printer
.popIndent()
.println("}")
} }
fun StringBuilder.renderNode(node: CFGNode<*>, index: Int) { override fun visitElement(element: FirElement) {
append(index.toString().padStart(maxLineNumberSize)) element.acceptChildren(this)
append(": ")
append(INDENT.repeat(node.level))
append(node.render())
append(" -> ")
append(node.followingNodes.renderEdges(node.isDead))
if (node.previousNodes.isNotEmpty()) {
append(" | <- ")
append(node.previousNodes.renderEdges(node.isDead))
}
appendln()
} }
with(builder) { override fun visitControlFlowGraphReference(controlFlowGraphReference: FirControlFlowGraphReference) {
val controlFlowGraph = (controlFlowGraphReference as? FirControlFlowGraphReferenceImpl)?.controlFlowGraph ?: return
indexOffset = controlFlowGraph.dotRenderToStringBuilder(printer)
printer.println()
}
private fun Printer.enterCluster(color: String) {
println("subgraph cluster_${clusterCounter++} {")
pushIndent()
println("color=$color")
}
private fun Printer.exitCluster() {
popIndent()
println("}")
}
private fun ControlFlowGraph.dotRenderToStringBuilder(printer: Printer): Int {
with(printer) {
val graph = this@dotRenderToStringBuilder
val sortedNodes = graph.sortNodes()
val indices = sortedNodes.indicesMap().mapValues { (_, index) -> index + indexOffset }
var color = RED
sortedNodes.forEach {
if (it is EnterNode) {
enterCluster(color)
color = BLUE
}
val attributes = mutableListOf<String>()
attributes += "label=\"${it.render().replace("\"", "")}\""
if (it == enterNode || it == exitNode) {
attributes += "style=\"filled\""
attributes += "fillcolor=red"
}
if (it.isDead) {
attributes += "style=\"filled\""
attributes += "fillcolor=gray"
}
println(indices.getValue(it), attributes.joinToString(separator = " ", prefix = " [", postfix = "];"))
if (it is ExitNode) {
exitCluster()
}
}
println()
sortedNodes.forEachIndexed { i, node -> sortedNodes.forEachIndexed { i, node ->
notVisited.remove(node) if (node.followingNodes.isEmpty()) return@forEachIndexed
renderNode(node, i)
fun renderEdges(kind: EdgeKind) {
val edges = node.followingNodes.filter { node.outgoingEdges.getValue(it) == kind }
if (edges.isEmpty()) return
print(
i + indexOffset,
EDGE,
edges.joinToString(prefix = "{", postfix = "}", separator = " ") { indices.getValue(it).toString() }
)
EDGE_STYLE.getValue(kind).takeIf { it.isNotBlank() }?.let { printWithNoIndent(" $it") }
printlnWithNoIndent(";")
} }
if (notVisited.isNotEmpty()) { for (kind in EdgeKind.values()) {
appendln("Not visited nodes:") renderEdges(kind)
notVisited.forEach { node ->
renderNode(node, indices.getValue(node))
} }
} }
appendln() return indexOffset + sortedNodes.size
}
} }
} }
fun ControlFlowGraph.render(): String = buildString { renderToStringBuilder(this) } private fun CFGNode<*>.render(): String =
fun CFGNode<*>.render(): String =
buildString { buildString {
append( append(
when (this@render) { when (this@render) {
@@ -154,7 +205,7 @@ fun CFGNode<*>.render(): String =
is ExitSafeCallNode -> "Exit safe call" is ExitSafeCallNode -> "Exit safe call"
else -> TODO(this@render.toString()) else -> TODO(this@render.toString())
} },
) )
} }
@@ -172,3 +223,16 @@ private fun FirLoop.type(): String = when (this) {
is FirDoWhileLoop -> "do-while" is FirDoWhileLoop -> "do-while"
else -> throw IllegalArgumentException() else -> throw IllegalArgumentException()
} }
private fun ControlFlowGraph.sortNodes(): List<CFGNode<*>> {
return DFS.topologicalOrder(nodes) {
val result = if (it !is WhenBranchConditionExitNode || it.followingNodes.size < 2) {
it.followingNodes
} else {
it.followingNodes.sortedBy { node -> if (node is BlockEnterNode) 1 else 0 }
}
result
}
}
private fun List<CFGNode<*>>.indicesMap(): Map<CFGNode<*>, Int> = mapIndexed { i, node -> node to i }.toMap()
@@ -71,23 +71,22 @@ digraph booleanOperatorsWithConsts_kt {
23 [label="Exit left part of ||"]; 23 [label="Exit left part of ||"];
24 [label="Enter right part of ||"]; 24 [label="Enter right part of ||"];
25 [label="Access variable R|<local>/b|"]; 25 [label="Access variable R|<local>/b|"];
26 [label="Stub" style="filled" fillcolor=gray]; 26 [label="Exit ||"];
27 [label="Exit ||"];
} }
28 [label="Exit when branch condition"]; 27 [label="Exit when branch condition"];
} }
29 [label="Synthetic else branch"]; 28 [label="Synthetic else branch"];
30 [label="Enter when branch result"]; 29 [label="Enter when branch result"];
subgraph cluster_9 { subgraph cluster_9 {
color=blue color=blue
31 [label="Enter block"]; 30 [label="Enter block"];
32 [label="Const: IntegerLiteral(1)"]; 31 [label="Const: IntegerLiteral(1)"];
33 [label="Exit block"]; 32 [label="Exit block"];
} }
34 [label="Exit when branch result"]; 33 [label="Exit when branch result"];
35 [label="Exit when"]; 34 [label="Exit when"];
} }
36 [label="Exit function test_2" style="filled" fillcolor=red]; 35 [label="Exit function test_2" style="filled" fillcolor=red];
} }
18 -> {19}; 18 -> {19};
@@ -98,337 +97,330 @@ digraph booleanOperatorsWithConsts_kt {
23 -> {24}; 23 -> {24};
23 -> {26} [style=dotted]; 23 -> {26} [style=dotted];
24 -> {25}; 24 -> {25};
25 -> {27}; 25 -> {26};
26 -> {27} [style=dotted]; 26 -> {27};
27 -> {28}; 27 -> {29 28};
28 -> {30 29}; 28 -> {34};
29 -> {35}; 29 -> {30};
30 -> {31}; 30 -> {31};
31 -> {32}; 31 -> {32};
32 -> {33}; 32 -> {33};
33 -> {34}; 33 -> {34};
34 -> {35}; 34 -> {35};
35 -> {36};
subgraph cluster_10 { subgraph cluster_10 {
color=red color=red
37 [label="Enter function test_3" style="filled" fillcolor=red]; 36 [label="Enter function test_3" style="filled" fillcolor=red];
subgraph cluster_11 { subgraph cluster_11 {
color=blue color=blue
38 [label="Enter when"]; 37 [label="Enter when"];
subgraph cluster_12 { subgraph cluster_12 {
color=blue color=blue
39 [label="Enter when branch condition "]; 38 [label="Enter when branch condition "];
subgraph cluster_13 { subgraph cluster_13 {
color=blue color=blue
40 [label="Enter ||"]; 39 [label="Enter ||"];
41 [label="Access variable R|<local>/b|"]; 40 [label="Access variable R|<local>/b|"];
42 [label="Exit left part of ||"]; 41 [label="Exit left part of ||"];
43 [label="Enter right part of ||"]; 42 [label="Enter right part of ||"];
44 [label="Const: Boolean(true)"]; 43 [label="Const: Boolean(true)"];
45 [label="Exit ||"]; 44 [label="Exit ||"];
} }
46 [label="Exit when branch condition"]; 45 [label="Exit when branch condition"];
} }
47 [label="Synthetic else branch"]; 46 [label="Synthetic else branch"];
48 [label="Enter when branch result"]; 47 [label="Enter when branch result"];
subgraph cluster_14 { subgraph cluster_14 {
color=blue color=blue
49 [label="Enter block"]; 48 [label="Enter block"];
50 [label="Const: IntegerLiteral(1)"]; 49 [label="Const: IntegerLiteral(1)"];
51 [label="Exit block"]; 50 [label="Exit block"];
} }
52 [label="Exit when branch result"]; 51 [label="Exit when branch result"];
53 [label="Exit when"]; 52 [label="Exit when"];
} }
54 [label="Exit function test_3" style="filled" fillcolor=red]; 53 [label="Exit function test_3" style="filled" fillcolor=red];
} }
36 -> {37};
37 -> {38}; 37 -> {38};
38 -> {39}; 38 -> {39};
39 -> {40}; 39 -> {40};
40 -> {41}; 40 -> {41};
41 -> {42}; 41 -> {44 42};
42 -> {45 43}; 42 -> {43};
43 -> {44}; 43 -> {44};
44 -> {45}; 44 -> {45};
45 -> {46}; 45 -> {47 46};
46 -> {48 47}; 46 -> {52};
47 -> {53}; 47 -> {48};
48 -> {49}; 48 -> {49};
49 -> {50}; 49 -> {50};
50 -> {51}; 50 -> {51};
51 -> {52}; 51 -> {52};
52 -> {53}; 52 -> {53};
53 -> {54};
subgraph cluster_15 { subgraph cluster_15 {
color=red color=red
55 [label="Enter function test_4" style="filled" fillcolor=red]; 54 [label="Enter function test_4" style="filled" fillcolor=red];
subgraph cluster_16 { subgraph cluster_16 {
color=blue color=blue
56 [label="Enter when"]; 55 [label="Enter when"];
subgraph cluster_17 { subgraph cluster_17 {
color=blue color=blue
57 [label="Enter when branch condition "]; 56 [label="Enter when branch condition "];
subgraph cluster_18 { subgraph cluster_18 {
color=blue color=blue
58 [label="Enter ||"]; 57 [label="Enter ||"];
59 [label="Const: Boolean(true)"]; 58 [label="Const: Boolean(true)"];
60 [label="Exit left part of ||"]; 59 [label="Exit left part of ||"];
61 [label="Stub" style="filled" fillcolor=gray]; 60 [label="Enter right part of ||" style="filled" fillcolor=gray];
62 [label="Enter right part of ||" style="filled" fillcolor=gray]; 61 [label="Access variable R|<local>/b|" style="filled" fillcolor=gray];
63 [label="Access variable R|<local>/b|" style="filled" fillcolor=gray]; 62 [label="Exit ||"];
64 [label="Exit ||"];
} }
65 [label="Exit when branch condition"]; 63 [label="Exit when branch condition"];
} }
66 [label="Synthetic else branch"]; 64 [label="Synthetic else branch"];
67 [label="Enter when branch result"]; 65 [label="Enter when branch result"];
subgraph cluster_19 { subgraph cluster_19 {
color=blue color=blue
68 [label="Enter block"]; 66 [label="Enter block"];
69 [label="Const: IntegerLiteral(1)"]; 67 [label="Const: IntegerLiteral(1)"];
70 [label="Exit block"]; 68 [label="Exit block"];
} }
71 [label="Exit when branch result"]; 69 [label="Exit when branch result"];
72 [label="Exit when"]; 70 [label="Exit when"];
} }
73 [label="Exit function test_4" style="filled" fillcolor=red]; 71 [label="Exit function test_4" style="filled" fillcolor=red];
} }
54 -> {55};
55 -> {56}; 55 -> {56};
56 -> {57}; 56 -> {57};
57 -> {58}; 57 -> {58};
58 -> {59}; 58 -> {59};
59 -> {60}; 59 -> {62};
60 -> {64}; 59 -> {60} [style=dotted];
60 -> {61} [style=dotted]; 60 -> {61} [style=dotted];
61 -> {62} [style=dotted]; 61 -> {62} [style=dotted];
62 -> {63} [style=dotted]; 62 -> {63};
63 -> {64} [style=dotted]; 63 -> {65 64};
64 -> {65}; 64 -> {70};
65 -> {67 66}; 65 -> {66};
66 -> {72}; 66 -> {67};
67 -> {68}; 67 -> {68};
68 -> {69}; 68 -> {69};
69 -> {70}; 69 -> {70};
70 -> {71}; 70 -> {71};
71 -> {72};
72 -> {73};
subgraph cluster_20 { subgraph cluster_20 {
color=red color=red
74 [label="Enter function test_5" style="filled" fillcolor=red]; 72 [label="Enter function test_5" style="filled" fillcolor=red];
subgraph cluster_21 { subgraph cluster_21 {
color=blue color=blue
75 [label="Enter when"]; 73 [label="Enter when"];
subgraph cluster_22 { subgraph cluster_22 {
color=blue color=blue
76 [label="Enter when branch condition "]; 74 [label="Enter when branch condition "];
subgraph cluster_23 { subgraph cluster_23 {
color=blue color=blue
77 [label="Enter &&"]; 75 [label="Enter &&"];
78 [label="Access variable R|<local>/b|"]; 76 [label="Access variable R|<local>/b|"];
79 [label="Exit left part of &&"]; 77 [label="Exit left part of &&"];
80 [label="Enter right part of &&"]; 78 [label="Enter right part of &&"];
81 [label="Const: Boolean(false)"]; 79 [label="Const: Boolean(false)"];
82 [label="Exit &&"]; 80 [label="Exit &&"];
} }
83 [label="Exit when branch condition"]; 81 [label="Exit when branch condition"];
} }
84 [label="Synthetic else branch"]; 82 [label="Synthetic else branch"];
85 [label="Enter when branch result"]; 83 [label="Enter when branch result"];
subgraph cluster_24 { subgraph cluster_24 {
color=blue color=blue
86 [label="Enter block"]; 84 [label="Enter block"];
87 [label="Const: IntegerLiteral(1)"]; 85 [label="Const: IntegerLiteral(1)"];
88 [label="Exit block"]; 86 [label="Exit block"];
} }
89 [label="Exit when branch result"]; 87 [label="Exit when branch result"];
90 [label="Exit when"]; 88 [label="Exit when"];
} }
91 [label="Exit function test_5" style="filled" fillcolor=red]; 89 [label="Exit function test_5" style="filled" fillcolor=red];
} }
72 -> {73};
73 -> {74};
74 -> {75}; 74 -> {75};
75 -> {76}; 75 -> {76};
76 -> {77}; 76 -> {77};
77 -> {78}; 77 -> {80 78};
78 -> {79}; 78 -> {79};
79 -> {82 80}; 79 -> {80};
80 -> {81}; 80 -> {81};
81 -> {82}; 81 -> {83 82};
82 -> {83}; 82 -> {88};
83 -> {85 84}; 83 -> {84};
84 -> {90}; 84 -> {85};
85 -> {86}; 85 -> {86};
86 -> {87}; 86 -> {87};
87 -> {88}; 87 -> {88};
88 -> {89}; 88 -> {89};
89 -> {90};
90 -> {91};
subgraph cluster_25 { subgraph cluster_25 {
color=red color=red
92 [label="Enter function test_6" style="filled" fillcolor=red]; 90 [label="Enter function test_6" style="filled" fillcolor=red];
subgraph cluster_26 { subgraph cluster_26 {
color=blue color=blue
93 [label="Enter when"]; 91 [label="Enter when"];
subgraph cluster_27 { subgraph cluster_27 {
color=blue color=blue
94 [label="Enter when branch condition "]; 92 [label="Enter when branch condition "];
subgraph cluster_28 { subgraph cluster_28 {
color=blue color=blue
95 [label="Enter &&"]; 93 [label="Enter &&"];
96 [label="Const: Boolean(false)"]; 94 [label="Const: Boolean(false)"];
97 [label="Exit left part of &&"]; 95 [label="Exit left part of &&"];
98 [label="Stub" style="filled" fillcolor=gray]; 96 [label="Enter right part of &&" style="filled" fillcolor=gray];
99 [label="Enter right part of &&" style="filled" fillcolor=gray]; 97 [label="Access variable R|<local>/b|" style="filled" fillcolor=gray];
100 [label="Access variable R|<local>/b|" style="filled" fillcolor=gray]; 98 [label="Exit &&"];
101 [label="Exit &&"];
} }
102 [label="Exit when branch condition"]; 99 [label="Exit when branch condition"];
} }
103 [label="Synthetic else branch"]; 100 [label="Synthetic else branch"];
104 [label="Enter when branch result"]; 101 [label="Enter when branch result"];
subgraph cluster_29 { subgraph cluster_29 {
color=blue color=blue
105 [label="Enter block"]; 102 [label="Enter block"];
106 [label="Const: IntegerLiteral(1)"]; 103 [label="Const: IntegerLiteral(1)"];
107 [label="Exit block"]; 104 [label="Exit block"];
} }
108 [label="Exit when branch result"]; 105 [label="Exit when branch result"];
109 [label="Exit when"]; 106 [label="Exit when"];
} }
110 [label="Exit function test_6" style="filled" fillcolor=red]; 107 [label="Exit function test_6" style="filled" fillcolor=red];
} }
90 -> {91};
91 -> {92};
92 -> {93}; 92 -> {93};
93 -> {94}; 93 -> {94};
94 -> {95}; 94 -> {95};
95 -> {96}; 95 -> {98};
96 -> {97}; 95 -> {96} [style=dotted];
97 -> {101}; 96 -> {97} [style=dotted];
97 -> {98} [style=dotted]; 97 -> {98} [style=dotted];
98 -> {99} [style=dotted]; 98 -> {99};
99 -> {100} [style=dotted]; 99 -> {101 100};
100 -> {101} [style=dotted]; 100 -> {106};
101 -> {102}; 101 -> {102};
102 -> {104 103}; 102 -> {103};
103 -> {109}; 103 -> {104};
104 -> {105}; 104 -> {105};
105 -> {106}; 105 -> {106};
106 -> {107}; 106 -> {107};
107 -> {108};
108 -> {109};
109 -> {110};
subgraph cluster_30 { subgraph cluster_30 {
color=red color=red
111 [label="Enter function test_7" style="filled" fillcolor=red]; 108 [label="Enter function test_7" style="filled" fillcolor=red];
subgraph cluster_31 { subgraph cluster_31 {
color=blue color=blue
112 [label="Enter when"]; 109 [label="Enter when"];
subgraph cluster_32 { subgraph cluster_32 {
color=blue color=blue
113 [label="Enter when branch condition "]; 110 [label="Enter when branch condition "];
subgraph cluster_33 { subgraph cluster_33 {
color=blue color=blue
114 [label="Enter &&"]; 111 [label="Enter &&"];
115 [label="Access variable R|<local>/b|"]; 112 [label="Access variable R|<local>/b|"];
116 [label="Exit left part of &&"]; 113 [label="Exit left part of &&"];
117 [label="Enter right part of &&"]; 114 [label="Enter right part of &&"];
118 [label="Const: Boolean(true)"]; 115 [label="Const: Boolean(true)"];
119 [label="Exit &&"]; 116 [label="Exit &&"];
} }
120 [label="Exit when branch condition"]; 117 [label="Exit when branch condition"];
} }
121 [label="Synthetic else branch"]; 118 [label="Synthetic else branch"];
122 [label="Enter when branch result"]; 119 [label="Enter when branch result"];
subgraph cluster_34 { subgraph cluster_34 {
color=blue color=blue
123 [label="Enter block"]; 120 [label="Enter block"];
124 [label="Const: IntegerLiteral(1)"]; 121 [label="Const: IntegerLiteral(1)"];
125 [label="Exit block"]; 122 [label="Exit block"];
} }
126 [label="Exit when branch result"]; 123 [label="Exit when branch result"];
127 [label="Exit when"]; 124 [label="Exit when"];
} }
128 [label="Exit function test_7" style="filled" fillcolor=red]; 125 [label="Exit function test_7" style="filled" fillcolor=red];
} }
108 -> {109};
109 -> {110};
110 -> {111};
111 -> {112}; 111 -> {112};
112 -> {113}; 112 -> {113};
113 -> {114}; 113 -> {116 114};
114 -> {115}; 114 -> {115};
115 -> {116}; 115 -> {116};
116 -> {119 117}; 116 -> {117};
117 -> {118}; 117 -> {119 118};
118 -> {119}; 118 -> {124};
119 -> {120}; 119 -> {120};
120 -> {122 121}; 120 -> {121};
121 -> {127}; 121 -> {122};
122 -> {123}; 122 -> {123};
123 -> {124}; 123 -> {124};
124 -> {125}; 124 -> {125};
125 -> {126};
126 -> {127};
127 -> {128};
subgraph cluster_35 { subgraph cluster_35 {
color=red color=red
129 [label="Enter function test_8" style="filled" fillcolor=red]; 126 [label="Enter function test_8" style="filled" fillcolor=red];
subgraph cluster_36 { subgraph cluster_36 {
color=blue color=blue
130 [label="Enter when"]; 127 [label="Enter when"];
subgraph cluster_37 { subgraph cluster_37 {
color=blue color=blue
131 [label="Enter when branch condition "]; 128 [label="Enter when branch condition "];
subgraph cluster_38 { subgraph cluster_38 {
color=blue color=blue
132 [label="Enter &&"]; 129 [label="Enter &&"];
133 [label="Const: Boolean(true)"]; 130 [label="Const: Boolean(true)"];
134 [label="Exit left part of &&"]; 131 [label="Exit left part of &&"];
135 [label="Enter right part of &&"]; 132 [label="Enter right part of &&"];
136 [label="Access variable R|<local>/b|"]; 133 [label="Access variable R|<local>/b|"];
137 [label="Stub" style="filled" fillcolor=gray]; 134 [label="Exit &&"];
138 [label="Exit &&"];
} }
139 [label="Exit when branch condition"]; 135 [label="Exit when branch condition"];
} }
140 [label="Synthetic else branch"]; 136 [label="Synthetic else branch"];
141 [label="Enter when branch result"]; 137 [label="Enter when branch result"];
subgraph cluster_39 { subgraph cluster_39 {
color=blue color=blue
142 [label="Enter block"]; 138 [label="Enter block"];
143 [label="Const: IntegerLiteral(1)"]; 139 [label="Const: IntegerLiteral(1)"];
144 [label="Exit block"]; 140 [label="Exit block"];
} }
145 [label="Exit when branch result"]; 141 [label="Exit when branch result"];
146 [label="Exit when"]; 142 [label="Exit when"];
} }
147 [label="Exit function test_8" style="filled" fillcolor=red]; 143 [label="Exit function test_8" style="filled" fillcolor=red];
} }
126 -> {127};
127 -> {128};
128 -> {129};
129 -> {130}; 129 -> {130};
130 -> {131}; 130 -> {131};
131 -> {132}; 131 -> {132};
131 -> {134} [style=dotted];
132 -> {133}; 132 -> {133};
133 -> {134}; 133 -> {134};
134 -> {135}; 134 -> {135};
134 -> {137} [style=dotted]; 135 -> {137 136};
135 -> {136}; 136 -> {142};
136 -> {138}; 137 -> {138};
137 -> {138} [style=dotted];
138 -> {139}; 138 -> {139};
139 -> {141 140}; 139 -> {140};
140 -> {146}; 140 -> {141};
141 -> {142}; 141 -> {142};
142 -> {143}; 142 -> {143};
143 -> {144};
144 -> {145};
145 -> {146};
146 -> {147};
} }
+85 -89
View File
@@ -172,12 +172,11 @@ digraph jumps_kt {
} }
64 [label="Exit loop block" style="filled" fillcolor=gray]; 64 [label="Exit loop block" style="filled" fillcolor=gray];
} }
65 [label="Stub" style="filled" fillcolor=gray]; 65 [label="Exit whileloop"];
66 [label="Exit whileloop"];
} }
67 [label="Access variable R|<local>/x|"]; 66 [label="Access variable R|<local>/x|"];
68 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()"]; 67 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()"];
69 [label="Exit function test_3" style="filled" fillcolor=red]; 68 [label="Exit function test_3" style="filled" fillcolor=red];
} }
52 -> {53}; 52 -> {53};
@@ -190,174 +189,171 @@ digraph jumps_kt {
58 -> {59}; 58 -> {59};
59 -> {60}; 59 -> {60};
60 -> {61}; 60 -> {61};
61 -> {66}; 61 -> {65};
61 -> {62} [style=dotted]; 61 -> {62} [style=dotted];
62 -> {63} [style=dotted]; 62 -> {63} [style=dotted];
63 -> {64} [style=dotted]; 63 -> {64} [style=dotted];
64 -> {54} [style=dotted]; 64 -> {54} [style=dotted];
65 -> {66} [style=dotted]; 65 -> {66};
66 -> {67}; 66 -> {67};
67 -> {68}; 67 -> {68};
68 -> {69};
subgraph cluster_17 { subgraph cluster_17 {
color=red color=red
70 [label="Enter function test_4" style="filled" fillcolor=red]; 69 [label="Enter function test_4" style="filled" fillcolor=red];
subgraph cluster_18 { subgraph cluster_18 {
color=blue color=blue
71 [label="Enter do-while loop"]; 70 [label="Enter do-while loop"];
subgraph cluster_19 { subgraph cluster_19 {
color=blue color=blue
72 [label="Enter loop block"]; 71 [label="Enter loop block"];
subgraph cluster_20 { subgraph cluster_20 {
color=blue color=blue
73 [label="Enter block"]; 72 [label="Enter block"];
74 [label="Access variable R|<local>/x|"]; 73 [label="Access variable R|<local>/x|"];
75 [label="Type operator: x as Int"]; 74 [label="Type operator: x as Int"];
76 [label="Jump: break@@@[Boolean(true)] "]; 75 [label="Jump: break@@@[Boolean(true)] "];
77 [label="Stub" style="filled" fillcolor=gray]; 76 [label="Stub" style="filled" fillcolor=gray];
78 [label="Exit block" style="filled" fillcolor=gray]; 77 [label="Exit block" style="filled" fillcolor=gray];
} }
79 [label="Exit loop block" style="filled" fillcolor=gray]; 78 [label="Exit loop block" style="filled" fillcolor=gray];
} }
subgraph cluster_21 { subgraph cluster_21 {
color=blue color=blue
80 [label="Enter loop condition" style="filled" fillcolor=gray]; 79 [label="Enter loop condition" style="filled" fillcolor=gray];
81 [label="Const: Boolean(true)" style="filled" fillcolor=gray]; 80 [label="Const: Boolean(true)" style="filled" fillcolor=gray];
82 [label="Exit loop condition" style="filled" fillcolor=gray]; 81 [label="Exit loop condition" style="filled" fillcolor=gray];
} }
83 [label="Stub" style="filled" fillcolor=gray]; 82 [label="Exit do-whileloop"];
84 [label="Exit do-whileloop"];
} }
85 [label="Access variable R|<local>/x|"]; 83 [label="Access variable R|<local>/x|"];
86 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()"]; 84 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()"];
87 [label="Exit function test_4" style="filled" fillcolor=red]; 85 [label="Exit function test_4" style="filled" fillcolor=red];
} }
69 -> {70};
70 -> {71}; 70 -> {71};
71 -> {72}; 71 -> {72};
72 -> {73}; 72 -> {73};
73 -> {74}; 73 -> {74};
74 -> {75}; 74 -> {75};
75 -> {76}; 75 -> {82};
76 -> {84}; 75 -> {76} [style=dotted];
76 -> {77} [style=dotted]; 76 -> {77} [style=dotted];
77 -> {78} [style=dotted]; 77 -> {78} [style=dotted];
78 -> {79} [style=dotted]; 78 -> {79} [style=dotted];
79 -> {80} [style=dotted]; 79 -> {80} [style=dotted];
80 -> {81} [style=dotted]; 80 -> {81} [style=dotted];
81 -> {82} [style=dotted]; 81 -> {71 82} [style=dotted];
82 -> {72 83} [style=dotted]; 82 -> {83};
83 -> {84} [style=dotted]; 83 -> {84};
84 -> {85}; 84 -> {85};
85 -> {86};
86 -> {87};
subgraph cluster_22 { subgraph cluster_22 {
color=red color=red
88 [label="Enter function test_5" style="filled" fillcolor=red]; 86 [label="Enter function test_5" style="filled" fillcolor=red];
subgraph cluster_23 { subgraph cluster_23 {
color=blue color=blue
89 [label="Enter while loop"]; 87 [label="Enter while loop"];
subgraph cluster_24 { subgraph cluster_24 {
color=blue color=blue
90 [label="Enter loop condition"]; 88 [label="Enter loop condition"];
91 [label="Access variable R|<local>/b|"]; 89 [label="Access variable R|<local>/b|"];
92 [label="Exit loop condition"]; 90 [label="Exit loop condition"];
} }
subgraph cluster_25 { subgraph cluster_25 {
color=blue color=blue
93 [label="Enter loop block"]; 91 [label="Enter loop block"];
subgraph cluster_26 { subgraph cluster_26 {
color=blue color=blue
94 [label="Enter block"]; 92 [label="Enter block"];
subgraph cluster_27 { subgraph cluster_27 {
color=blue color=blue
95 [label="Enter when"]; 93 [label="Enter when"];
subgraph cluster_28 { subgraph cluster_28 {
color=blue color=blue
96 [label="Enter when branch condition "]; 94 [label="Enter when branch condition "];
97 [label="Access variable R|<local>/b|"]; 95 [label="Access variable R|<local>/b|"];
98 [label="Exit when branch condition"]; 96 [label="Exit when branch condition"];
} }
99 [label="Synthetic else branch"]; 97 [label="Synthetic else branch"];
100 [label="Enter when branch result"]; 98 [label="Enter when branch result"];
subgraph cluster_29 { subgraph cluster_29 {
color=blue color=blue
101 [label="Enter block"]; 99 [label="Enter block"];
102 [label="Jump: continue@@@[R|<local>/b|] "]; 100 [label="Jump: continue@@@[R|<local>/b|] "];
103 [label="Stub" style="filled" fillcolor=gray]; 101 [label="Stub" style="filled" fillcolor=gray];
104 [label="Exit block" style="filled" fillcolor=gray]; 102 [label="Exit block" style="filled" fillcolor=gray];
} }
105 [label="Exit when branch result" style="filled" fillcolor=gray]; 103 [label="Exit when branch result" style="filled" fillcolor=gray];
106 [label="Exit when"]; 104 [label="Exit when"];
} }
107 [label="Exit block"]; 105 [label="Exit block"];
} }
108 [label="Exit loop block"]; 106 [label="Exit loop block"];
} }
109 [label="Exit whileloop"]; 107 [label="Exit whileloop"];
} }
110 [label="Exit function test_5" style="filled" fillcolor=red]; 108 [label="Exit function test_5" style="filled" fillcolor=red];
} }
86 -> {87};
87 -> {88};
88 -> {89}; 88 -> {89};
89 -> {90}; 89 -> {90};
90 -> {91}; 90 -> {107 91};
91 -> {92}; 91 -> {92};
92 -> {109 93}; 92 -> {93};
93 -> {94}; 93 -> {94};
94 -> {95}; 94 -> {95};
95 -> {96}; 95 -> {96};
96 -> {97}; 96 -> {98 97};
97 -> {98}; 97 -> {104};
98 -> {100 99}; 98 -> {99};
99 -> {106}; 99 -> {100};
100 -> {101}; 100 -> {87};
101 -> {102}; 100 -> {101} [style=dotted];
102 -> {89}; 101 -> {102} [style=dotted];
102 -> {103} [style=dotted]; 102 -> {103} [style=dotted];
103 -> {104} [style=dotted]; 103 -> {104} [style=dotted];
104 -> {105} [style=dotted]; 104 -> {105};
105 -> {106} [style=dotted]; 105 -> {106};
106 -> {107}; 106 -> {88};
107 -> {108}; 107 -> {108};
108 -> {90};
109 -> {110};
subgraph cluster_30 { subgraph cluster_30 {
color=red color=red
111 [label="Enter function run" style="filled" fillcolor=red]; 109 [label="Enter function run" style="filled" fillcolor=red];
112 [label="Function call: R|<local>/block|.R|FakeOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()"]; 110 [label="Function call: R|<local>/block|.R|FakeOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()"];
113 [label="Exit function run" style="filled" fillcolor=red]; 111 [label="Exit function run" style="filled" fillcolor=red];
} }
111 -> {112}; 109 -> {110};
112 -> {113}; 110 -> {111};
subgraph cluster_31 { subgraph cluster_31 {
color=red color=red
114 [label="Enter function test_6" style="filled" fillcolor=red]; 112 [label="Enter function test_6" style="filled" fillcolor=red];
subgraph cluster_32 { subgraph cluster_32 {
color=blue color=blue
115 [label="Enter function anonymousFunction"]; 113 [label="Enter function anonymousFunction"];
116 [label="Jump: ^@run Unit"]; 114 [label="Jump: ^@run Unit"];
117 [label="Stub" style="filled" fillcolor=gray]; 115 [label="Stub" style="filled" fillcolor=gray];
118 [label="Exit function anonymousFunction"]; 116 [label="Exit function anonymousFunction"];
} }
119 [label="Function call: R|/run|(<L> = run@fun <anonymous>(): R|kotlin/Unit| <kind=UNKNOWN> { 117 [label="Function call: R|/run|(<L> = run@fun <anonymous>(): R|kotlin/Unit| <kind=UNKNOWN> {
^@run Unit ^@run Unit
} }
)"]; )"];
120 [label="Exit function test_6" style="filled" fillcolor=red]; 118 [label="Exit function test_6" style="filled" fillcolor=red];
} }
114 -> {115}; 112 -> {113};
115 -> {118 116}; 113 -> {116 114};
116 -> {118}; 114 -> {116};
116 -> {117} [style=dotted]; 114 -> {115} [style=dotted];
117 -> {118} [style=dotted]; 115 -> {116} [style=dotted];
118 -> {115 119}; 116 -> {113 117};
119 -> {120}; 117 -> {118};
} }
+363
View File
@@ -0,0 +1,363 @@
digraph jumps_kt {
graph [splines=ortho nodesep=3]
node [shape=box penwidth=2]
edge [penwidth=2]
subgraph cluster_0 {
color=red
0 [label="Enter function test_1" style="filled" fillcolor=red];
subgraph cluster_1 {
color=blue
1 [label="Enter when"];
subgraph cluster_2 {
color=blue
2 [label="Enter when branch condition "];
3 [label="Access variable R|<local>/x|"];
4 [label="Const: Null(null)"];
5 [label="Operator =="];
6 [label="Exit when branch condition"];
}
subgraph cluster_3 {
color=blue
7 [label="Enter when branch condition else"];
8 [label="Exit when branch condition"];
}
9 [label="Enter when branch result"];
subgraph cluster_4 {
color=blue
10 [label="Enter block"];
11 [label="Access variable R|<local>/x|"];
12 [label="Exit block"];
}
13 [label="Exit when branch result"];
14 [label="Enter when branch result"];
subgraph cluster_5 {
color=blue
15 [label="Enter block"];
16 [label="Function call: R|kotlin/KotlinNullPointerException.KotlinNullPointerException|()"];
17 [label="Throw: throw R|kotlin/KotlinNullPointerException.KotlinNullPointerException|()"];
18 [label="Stub" style="filled" fillcolor=gray];
19 [label="Exit block" style="filled" fillcolor=gray];
}
20 [label="Exit when branch result" style="filled" fillcolor=gray];
21 [label="Exit when"];
}
22 [label="Variable declaration: lval y: R|kotlin/Int|"];
23 [label="Access variable R|<local>/y|"];
24 [label="Function call: R|<local>/y|.R|kotlin/Int.inc|()"];
25 [label="Access variable R|<local>/x|"];
26 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()"];
27 [label="Exit function test_1" style="filled" fillcolor=red];
}
0 -> {1};
1 -> {2};
2 -> {3};
3 -> {4};
4 -> {5};
5 -> {6};
6 -> {14 7};
7 -> {8};
8 -> {9};
9 -> {10};
10 -> {11};
11 -> {12};
12 -> {13};
13 -> {21};
14 -> {15};
15 -> {16};
16 -> {17};
17 -> {27};
17 -> {18} [style=dotted];
18 -> {19} [style=dotted];
19 -> {20} [style=dotted];
20 -> {21} [style=dotted];
21 -> {22};
22 -> {23};
23 -> {24};
24 -> {25};
25 -> {26};
26 -> {27};
subgraph cluster_6 {
color=red
28 [label="Enter function test_2" style="filled" fillcolor=red];
subgraph cluster_7 {
color=blue
29 [label="Enter when"];
subgraph cluster_8 {
color=blue
30 [label="Enter when branch condition "];
31 [label="Access variable R|<local>/x|"];
32 [label="Const: Null(null)"];
33 [label="Operator =="];
34 [label="Exit when branch condition"];
}
subgraph cluster_9 {
color=blue
35 [label="Enter when branch condition else"];
36 [label="Exit when branch condition"];
}
37 [label="Enter when branch result"];
subgraph cluster_10 {
color=blue
38 [label="Enter block"];
39 [label="Access variable R|<local>/x|"];
40 [label="Exit block"];
}
41 [label="Exit when branch result"];
42 [label="Enter when branch result"];
subgraph cluster_11 {
color=blue
43 [label="Enter block"];
44 [label="Access variable R|<local>/x|"];
45 [label="Exit block"];
}
46 [label="Exit when branch result"];
47 [label="Exit when"];
}
48 [label="Variable declaration: lval y: R|kotlin/Int?|"];
49 [label="Access variable R|<local>/y|"];
50 [label="Function call: R|<local>/y|.<Ambiguity: inc, [kotlin/inc, kotlin/inc]>#()"];
51 [label="Exit function test_2" style="filled" fillcolor=red];
}
28 -> {29};
29 -> {30};
30 -> {31};
31 -> {32};
32 -> {33};
33 -> {34};
34 -> {42 35};
35 -> {36};
36 -> {37};
37 -> {38};
38 -> {39};
39 -> {40};
40 -> {41};
41 -> {47};
42 -> {43};
43 -> {44};
44 -> {45};
45 -> {46};
46 -> {47};
47 -> {48};
48 -> {49};
49 -> {50};
50 -> {51};
subgraph cluster_12 {
color=red
52 [label="Enter function test_3" style="filled" fillcolor=red];
subgraph cluster_13 {
color=blue
53 [label="Enter while loop"];
subgraph cluster_14 {
color=blue
54 [label="Enter loop condition"];
55 [label="Const: Boolean(true)"];
56 [label="Exit loop condition"];
}
subgraph cluster_15 {
color=blue
57 [label="Enter loop block"];
subgraph cluster_16 {
color=blue
58 [label="Enter block"];
59 [label="Access variable R|<local>/x|"];
60 [label="Type operator: x as Int"];
61 [label="Jump: break@@@[Boolean(true)] "];
62 [label="Stub" style="filled" fillcolor=gray];
63 [label="Exit block" style="filled" fillcolor=gray];
}
64 [label="Exit loop block" style="filled" fillcolor=gray];
}
65 [label="Stub" style="filled" fillcolor=gray];
66 [label="Exit whileloop"];
}
67 [label="Access variable R|<local>/x|"];
68 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()"];
69 [label="Exit function test_3" style="filled" fillcolor=red];
}
52 -> {53};
53 -> {54};
54 -> {55};
55 -> {56};
56 -> {57};
56 -> {65} [style=dotted];
57 -> {58};
58 -> {59};
59 -> {60};
60 -> {61};
61 -> {66};
61 -> {62} [style=dotted];
62 -> {63} [style=dotted];
63 -> {64} [style=dotted];
64 -> {54} [style=dotted];
65 -> {66} [style=dotted];
66 -> {67};
67 -> {68};
68 -> {69};
subgraph cluster_17 {
color=red
70 [label="Enter function test_4" style="filled" fillcolor=red];
subgraph cluster_18 {
color=blue
71 [label="Enter do-while loop"];
subgraph cluster_19 {
color=blue
72 [label="Enter loop block"];
subgraph cluster_20 {
color=blue
73 [label="Enter block"];
74 [label="Access variable R|<local>/x|"];
75 [label="Type operator: x as Int"];
76 [label="Jump: break@@@[Boolean(true)] "];
77 [label="Stub" style="filled" fillcolor=gray];
78 [label="Exit block" style="filled" fillcolor=gray];
}
79 [label="Exit loop block" style="filled" fillcolor=gray];
}
subgraph cluster_21 {
color=blue
80 [label="Enter loop condition" style="filled" fillcolor=gray];
81 [label="Const: Boolean(true)" style="filled" fillcolor=gray];
82 [label="Exit loop condition" style="filled" fillcolor=gray];
}
83 [label="Stub" style="filled" fillcolor=gray];
84 [label="Exit do-whileloop"];
}
85 [label="Access variable R|<local>/x|"];
86 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()"];
87 [label="Exit function test_4" style="filled" fillcolor=red];
}
70 -> {71};
71 -> {72};
72 -> {73};
73 -> {74};
74 -> {75};
75 -> {76};
76 -> {84};
76 -> {77} [style=dotted];
77 -> {78} [style=dotted];
78 -> {79} [style=dotted];
79 -> {80} [style=dotted];
80 -> {81} [style=dotted];
81 -> {82} [style=dotted];
82 -> {72 83} [style=dotted];
83 -> {84} [style=dotted];
84 -> {85};
85 -> {86};
86 -> {87};
subgraph cluster_22 {
color=red
88 [label="Enter function test_5" style="filled" fillcolor=red];
subgraph cluster_23 {
color=blue
89 [label="Enter while loop"];
subgraph cluster_24 {
color=blue
90 [label="Enter loop condition"];
91 [label="Access variable R|<local>/b|"];
92 [label="Exit loop condition"];
}
subgraph cluster_25 {
color=blue
93 [label="Enter loop block"];
subgraph cluster_26 {
color=blue
94 [label="Enter block"];
subgraph cluster_27 {
color=blue
95 [label="Enter when"];
subgraph cluster_28 {
color=blue
96 [label="Enter when branch condition "];
97 [label="Access variable R|<local>/b|"];
98 [label="Exit when branch condition"];
}
99 [label="Synthetic else branch"];
100 [label="Enter when branch result"];
subgraph cluster_29 {
color=blue
101 [label="Enter block"];
102 [label="Jump: continue@@@[R|<local>/b|] "];
103 [label="Stub" style="filled" fillcolor=gray];
104 [label="Exit block" style="filled" fillcolor=gray];
}
105 [label="Exit when branch result" style="filled" fillcolor=gray];
106 [label="Exit when"];
}
107 [label="Exit block"];
}
108 [label="Exit loop block"];
}
109 [label="Exit whileloop"];
}
110 [label="Exit function test_5" style="filled" fillcolor=red];
}
88 -> {89};
89 -> {90};
90 -> {91};
91 -> {92};
92 -> {109 93};
93 -> {94};
94 -> {95};
95 -> {96};
96 -> {97};
97 -> {98};
98 -> {100 99};
99 -> {106};
100 -> {101};
101 -> {102};
102 -> {89};
102 -> {103} [style=dotted];
103 -> {104} [style=dotted];
104 -> {105} [style=dotted];
105 -> {106} [style=dotted];
106 -> {107};
107 -> {108};
108 -> {90};
109 -> {110};
subgraph cluster_30 {
color=red
111 [label="Enter function run" style="filled" fillcolor=red];
112 [label="Function call: R|<local>/block|.R|FakeOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()"];
113 [label="Exit function run" style="filled" fillcolor=red];
}
111 -> {112};
112 -> {113};
subgraph cluster_31 {
color=red
114 [label="Enter function test_6" style="filled" fillcolor=red];
subgraph cluster_32 {
color=blue
115 [label="Enter function anonymousFunction"];
116 [label="Jump: ^@run Unit"];
117 [label="Stub" style="filled" fillcolor=gray];
118 [label="Exit function anonymousFunction"];
}
119 [label="Function call: R|/run|(<L> = run@fun <anonymous>(): R|kotlin/Unit| <kind=UNKNOWN> {
^@run Unit
}
)"];
120 [label="Exit function test_6" style="filled" fillcolor=red];
}
114 -> {115};
115 -> {118 116};
116 -> {118};
116 -> {117} [style=dotted];
117 -> {118} [style=dotted];
118 -> {115 119};
119 -> {120};
}
+358
View File
@@ -0,0 +1,358 @@
digraph jumps_kt {
graph [splines=ortho nodesep=3]
node [shape=box penwidth=2]
edge [penwidth=2]
subgraph cluster_0 {
color=red
0 [label="Enter function test_1" style="filled" fillcolor=red];
subgraph cluster_1 {
color=blue
1 [label="Enter when"];
subgraph cluster_2 {
color=blue
2 [label="Enter when branch condition "];
3 [label="Access variable R|<local>/x|"];
4 [label="Const: Null(null)"];
5 [label="Operator =="];
6 [label="Exit when branch condition"];
}
subgraph cluster_3 {
color=blue
7 [label="Enter when branch condition else"];
8 [label="Exit when branch condition"];
}
9 [label="Enter when branch result"];
subgraph cluster_4 {
color=blue
10 [label="Enter block"];
11 [label="Access variable R|<local>/x|"];
12 [label="Exit block"];
}
13 [label="Exit when branch result"];
14 [label="Enter when branch result"];
subgraph cluster_5 {
color=blue
15 [label="Enter block"];
16 [label="Function call: R|kotlin/KotlinNullPointerException.KotlinNullPointerException|()"];
17 [label="Throw: throw R|kotlin/KotlinNullPointerException.KotlinNullPointerException|()"];
18 [label="Stub" style="filled" fillcolor=gray];
19 [label="Exit block" style="filled" fillcolor=gray];
}
20 [label="Exit when branch result" style="filled" fillcolor=gray];
21 [label="Exit when"];
}
22 [label="Variable declaration: lval y: R|kotlin/Int|"];
23 [label="Access variable R|<local>/y|"];
24 [label="Function call: R|<local>/y|.R|kotlin/Int.inc|()"];
25 [label="Access variable R|<local>/x|"];
26 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()"];
27 [label="Exit function test_1" style="filled" fillcolor=red];
}
0 -> {1};
1 -> {2};
2 -> {3};
3 -> {4};
4 -> {5};
5 -> {6};
6 -> {14 7};
7 -> {8};
8 -> {9};
9 -> {10};
10 -> {11};
11 -> {12};
12 -> {13};
13 -> {21};
14 -> {15};
15 -> {16};
16 -> {17};
17 -> {27};
17 -> {18} [style=dotted];
18 -> {19} [style=dotted];
19 -> {20} [style=dotted];
20 -> {21} [style=dotted];
21 -> {22};
22 -> {23};
23 -> {24};
24 -> {25};
25 -> {26};
26 -> {27};
subgraph cluster_6 {
color=red
28 [label="Enter function test_2" style="filled" fillcolor=red];
subgraph cluster_7 {
color=blue
29 [label="Enter when"];
subgraph cluster_8 {
color=blue
30 [label="Enter when branch condition "];
31 [label="Access variable R|<local>/x|"];
32 [label="Const: Null(null)"];
33 [label="Operator =="];
34 [label="Exit when branch condition"];
}
subgraph cluster_9 {
color=blue
35 [label="Enter when branch condition else"];
36 [label="Exit when branch condition"];
}
37 [label="Enter when branch result"];
subgraph cluster_10 {
color=blue
38 [label="Enter block"];
39 [label="Access variable R|<local>/x|"];
40 [label="Exit block"];
}
41 [label="Exit when branch result"];
42 [label="Enter when branch result"];
subgraph cluster_11 {
color=blue
43 [label="Enter block"];
44 [label="Access variable R|<local>/x|"];
45 [label="Exit block"];
}
46 [label="Exit when branch result"];
47 [label="Exit when"];
}
48 [label="Variable declaration: lval y: R|kotlin/Int?|"];
49 [label="Access variable R|<local>/y|"];
50 [label="Function call: R|<local>/y|.<Ambiguity: inc, [kotlin/inc, kotlin/inc]>#()"];
51 [label="Exit function test_2" style="filled" fillcolor=red];
}
28 -> {29};
29 -> {30};
30 -> {31};
31 -> {32};
32 -> {33};
33 -> {34};
34 -> {42 35};
35 -> {36};
36 -> {37};
37 -> {38};
38 -> {39};
39 -> {40};
40 -> {41};
41 -> {47};
42 -> {43};
43 -> {44};
44 -> {45};
45 -> {46};
46 -> {47};
47 -> {48};
48 -> {49};
49 -> {50};
50 -> {51};
subgraph cluster_12 {
color=red
52 [label="Enter function test_3" style="filled" fillcolor=red];
subgraph cluster_13 {
color=blue
53 [label="Enter while loop"];
subgraph cluster_14 {
color=blue
54 [label="Enter loop condition"];
55 [label="Const: Boolean(true)"];
56 [label="Exit loop condition"];
}
subgraph cluster_15 {
color=blue
57 [label="Enter loop block"];
subgraph cluster_16 {
color=blue
58 [label="Enter block"];
59 [label="Access variable R|<local>/x|"];
60 [label="Type operator: x as Int"];
61 [label="Jump: break@@@[Boolean(true)] "];
62 [label="Stub" style="filled" fillcolor=gray];
63 [label="Exit block" style="filled" fillcolor=gray];
}
64 [label="Exit loop block" style="filled" fillcolor=gray];
}
65 [label="Exit whileloop"];
}
66 [label="Access variable R|<local>/x|"];
67 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()"];
68 [label="Exit function test_3" style="filled" fillcolor=red];
}
52 -> {53};
53 -> {54};
54 -> {55};
55 -> {56};
56 -> {65 57};
57 -> {58};
58 -> {59};
59 -> {60};
60 -> {61};
61 -> {65};
61 -> {62} [style=dotted];
62 -> {63} [style=dotted];
63 -> {64} [style=dotted];
64 -> {54} [style=dotted];
65 -> {66};
66 -> {67};
67 -> {68};
subgraph cluster_17 {
color=red
69 [label="Enter function test_4" style="filled" fillcolor=red];
subgraph cluster_18 {
color=blue
70 [label="Enter do-while loop"];
subgraph cluster_19 {
color=blue
71 [label="Enter loop block"];
subgraph cluster_20 {
color=blue
72 [label="Enter block"];
73 [label="Access variable R|<local>/x|"];
74 [label="Type operator: x as Int"];
75 [label="Jump: break@@@[Boolean(true)] "];
76 [label="Stub" style="filled" fillcolor=gray];
77 [label="Exit block" style="filled" fillcolor=gray];
}
78 [label="Exit loop block" style="filled" fillcolor=gray];
}
subgraph cluster_21 {
color=blue
79 [label="Enter loop condition" style="filled" fillcolor=gray];
80 [label="Const: Boolean(true)" style="filled" fillcolor=gray];
81 [label="Exit loop condition" style="filled" fillcolor=gray];
}
82 [label="Exit do-whileloop"];
}
83 [label="Access variable R|<local>/x|"];
84 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()"];
85 [label="Exit function test_4" style="filled" fillcolor=red];
}
69 -> {70};
70 -> {71};
71 -> {72};
72 -> {73};
73 -> {74};
74 -> {75};
75 -> {82};
75 -> {76} [style=dotted];
76 -> {77} [style=dotted];
77 -> {78} [style=dotted];
78 -> {79} [style=dotted];
79 -> {80} [style=dotted];
80 -> {81} [style=dotted];
81 -> {71 82} [style=dotted];
82 -> {83};
83 -> {84};
84 -> {85};
subgraph cluster_22 {
color=red
86 [label="Enter function test_5" style="filled" fillcolor=red];
subgraph cluster_23 {
color=blue
87 [label="Enter while loop"];
subgraph cluster_24 {
color=blue
88 [label="Enter loop condition"];
89 [label="Access variable R|<local>/b|"];
90 [label="Exit loop condition"];
}
subgraph cluster_25 {
color=blue
91 [label="Enter loop block"];
subgraph cluster_26 {
color=blue
92 [label="Enter block"];
subgraph cluster_27 {
color=blue
93 [label="Enter when"];
subgraph cluster_28 {
color=blue
94 [label="Enter when branch condition "];
95 [label="Access variable R|<local>/b|"];
96 [label="Exit when branch condition"];
}
97 [label="Synthetic else branch"];
98 [label="Enter when branch result"];
subgraph cluster_29 {
color=blue
99 [label="Enter block"];
100 [label="Jump: continue@@@[R|<local>/b|] "];
101 [label="Stub" style="filled" fillcolor=gray];
102 [label="Exit block" style="filled" fillcolor=gray];
}
103 [label="Exit when branch result" style="filled" fillcolor=gray];
104 [label="Exit when"];
}
105 [label="Exit block"];
}
106 [label="Exit loop block"];
}
107 [label="Exit whileloop"];
}
108 [label="Exit function test_5" style="filled" fillcolor=red];
}
86 -> {87};
87 -> {88};
88 -> {89};
89 -> {90};
90 -> {107 91};
91 -> {92};
92 -> {93};
93 -> {94};
94 -> {95};
95 -> {96};
96 -> {98 97};
97 -> {104};
98 -> {99};
99 -> {100};
100 -> {87};
100 -> {101} [style=dotted];
101 -> {102} [style=dotted];
102 -> {103} [style=dotted];
103 -> {104} [style=dotted];
104 -> {105};
105 -> {106};
106 -> {88};
107 -> {108};
subgraph cluster_30 {
color=red
109 [label="Enter function run" style="filled" fillcolor=red];
110 [label="Function call: R|<local>/block|.R|FakeOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()"];
111 [label="Exit function run" style="filled" fillcolor=red];
}
109 -> {110};
110 -> {111};
subgraph cluster_31 {
color=red
112 [label="Enter function test_6" style="filled" fillcolor=red];
subgraph cluster_32 {
color=blue
113 [label="Enter function anonymousFunction"];
114 [label="Jump: ^@run Unit"];
115 [label="Stub" style="filled" fillcolor=gray];
116 [label="Exit function anonymousFunction"];
}
117 [label="Function call: R|/run|(<L> = run@fun <anonymous>(): R|kotlin/Unit| <kind=UNKNOWN> {
^@run Unit
}
)"];
118 [label="Exit function test_6" style="filled" fillcolor=red];
}
112 -> {113};
113 -> {116 114};
114 -> {116};
114 -> {115} [style=dotted];
115 -> {116} [style=dotted];
116 -> {113 117};
117 -> {118};
}
+139 -151
View File
@@ -192,11 +192,10 @@ digraph loops_kt {
} }
68 [label="Exit loop block"]; 68 [label="Exit loop block"];
} }
69 [label="Stub" style="filled" fillcolor=gray]; 69 [label="Exit whileloop" style="filled" fillcolor=gray];
70 [label="Exit whileloop" style="filled" fillcolor=gray];
} }
71 [label="Const: Int(1)" style="filled" fillcolor=gray]; 70 [label="Const: Int(1)" style="filled" fillcolor=gray];
72 [label="Exit function testWhileTrue" style="filled" fillcolor=red style="filled" fillcolor=gray]; 71 [label="Exit function testWhileTrue" style="filled" fillcolor=red style="filled" fillcolor=gray];
} }
59 -> {60}; 59 -> {60};
@@ -212,295 +211,284 @@ digraph loops_kt {
68 -> {61}; 68 -> {61};
69 -> {70} [style=dotted]; 69 -> {70} [style=dotted];
70 -> {71} [style=dotted]; 70 -> {71} [style=dotted];
71 -> {72} [style=dotted];
subgraph cluster_20 { subgraph cluster_20 {
color=red color=red
73 [label="Enter function testWhileTrueWithBreak" style="filled" fillcolor=red]; 72 [label="Enter function testWhileTrueWithBreak" style="filled" fillcolor=red];
subgraph cluster_21 { subgraph cluster_21 {
color=blue color=blue
74 [label="Enter while loop"]; 73 [label="Enter while loop"];
subgraph cluster_22 { subgraph cluster_22 {
color=blue color=blue
75 [label="Enter loop condition"]; 74 [label="Enter loop condition"];
76 [label="Const: Boolean(true)"]; 75 [label="Const: Boolean(true)"];
77 [label="Exit loop condition"]; 76 [label="Exit loop condition"];
} }
subgraph cluster_23 { subgraph cluster_23 {
color=blue color=blue
78 [label="Enter loop block"]; 77 [label="Enter loop block"];
subgraph cluster_24 { subgraph cluster_24 {
color=blue color=blue
79 [label="Enter block"]; 78 [label="Enter block"];
subgraph cluster_25 { subgraph cluster_25 {
color=blue color=blue
80 [label="Enter when"]; 79 [label="Enter when"];
subgraph cluster_26 { subgraph cluster_26 {
color=blue color=blue
81 [label="Enter when branch condition "]; 80 [label="Enter when branch condition "];
82 [label="Access variable R|<local>/b|"]; 81 [label="Access variable R|<local>/b|"];
83 [label="Exit when branch condition"]; 82 [label="Exit when branch condition"];
} }
84 [label="Synthetic else branch"]; 83 [label="Synthetic else branch"];
85 [label="Enter when branch result"]; 84 [label="Enter when branch result"];
subgraph cluster_27 { subgraph cluster_27 {
color=blue color=blue
86 [label="Enter block"]; 85 [label="Enter block"];
87 [label="Jump: break@@@[Boolean(true)] "]; 86 [label="Jump: break@@@[Boolean(true)] "];
88 [label="Stub" style="filled" fillcolor=gray]; 87 [label="Stub" style="filled" fillcolor=gray];
89 [label="Exit block" style="filled" fillcolor=gray]; 88 [label="Exit block" style="filled" fillcolor=gray];
} }
90 [label="Exit when branch result" style="filled" fillcolor=gray]; 89 [label="Exit when branch result" style="filled" fillcolor=gray];
91 [label="Exit when"]; 90 [label="Exit when"];
} }
92 [label="Exit block"]; 91 [label="Exit block"];
} }
93 [label="Exit loop block"]; 92 [label="Exit loop block"];
} }
94 [label="Stub" style="filled" fillcolor=gray]; 93 [label="Exit whileloop"];
95 [label="Exit whileloop"];
} }
96 [label="Const: Int(1)"]; 94 [label="Const: Int(1)"];
97 [label="Exit function testWhileTrueWithBreak" style="filled" fillcolor=red]; 95 [label="Exit function testWhileTrueWithBreak" style="filled" fillcolor=red];
} }
72 -> {73};
73 -> {74}; 73 -> {74};
74 -> {75}; 74 -> {75};
75 -> {76}; 75 -> {76};
76 -> {77}; 76 -> {77};
76 -> {93} [style=dotted];
77 -> {78}; 77 -> {78};
77 -> {94} [style=dotted];
78 -> {79}; 78 -> {79};
79 -> {80}; 79 -> {80};
80 -> {81}; 80 -> {81};
81 -> {82}; 81 -> {82};
82 -> {83}; 82 -> {84 83};
83 -> {85 84}; 83 -> {90};
84 -> {91}; 84 -> {85};
85 -> {86}; 85 -> {86};
86 -> {87}; 86 -> {93};
87 -> {95}; 86 -> {87} [style=dotted];
87 -> {88} [style=dotted]; 87 -> {88} [style=dotted];
88 -> {89} [style=dotted]; 88 -> {89} [style=dotted];
89 -> {90} [style=dotted]; 89 -> {90} [style=dotted];
90 -> {91} [style=dotted]; 90 -> {91};
91 -> {92}; 91 -> {92};
92 -> {93}; 92 -> {74};
93 -> {75}; 93 -> {94};
94 -> {95} [style=dotted]; 94 -> {95};
95 -> {96};
96 -> {97};
subgraph cluster_28 { subgraph cluster_28 {
color=red color=red
98 [label="Enter function testWhileFalse" style="filled" fillcolor=red]; 96 [label="Enter function testWhileFalse" style="filled" fillcolor=red];
subgraph cluster_29 { subgraph cluster_29 {
color=blue color=blue
99 [label="Enter while loop"]; 97 [label="Enter while loop"];
subgraph cluster_30 { subgraph cluster_30 {
color=blue color=blue
100 [label="Enter loop condition"]; 98 [label="Enter loop condition"];
101 [label="Const: Boolean(false)"]; 99 [label="Const: Boolean(false)"];
102 [label="Exit loop condition"]; 100 [label="Exit loop condition"];
} }
103 [label="Stub" style="filled" fillcolor=gray];
subgraph cluster_31 { subgraph cluster_31 {
color=blue color=blue
104 [label="Enter loop block" style="filled" fillcolor=gray]; 101 [label="Enter loop block" style="filled" fillcolor=gray];
subgraph cluster_32 { subgraph cluster_32 {
color=blue color=blue
105 [label="Enter block" style="filled" fillcolor=gray]; 102 [label="Enter block" style="filled" fillcolor=gray];
106 [label="Const: Int(1)" style="filled" fillcolor=gray]; 103 [label="Const: Int(1)" style="filled" fillcolor=gray];
107 [label="Exit block" style="filled" fillcolor=gray]; 104 [label="Exit block" style="filled" fillcolor=gray];
} }
108 [label="Exit loop block" style="filled" fillcolor=gray]; 105 [label="Exit loop block" style="filled" fillcolor=gray];
} }
109 [label="Exit whileloop"]; 106 [label="Exit whileloop"];
} }
110 [label="Const: Int(1)"]; 107 [label="Const: Int(1)"];
111 [label="Exit function testWhileFalse" style="filled" fillcolor=red]; 108 [label="Exit function testWhileFalse" style="filled" fillcolor=red];
} }
96 -> {97};
97 -> {98};
98 -> {99}; 98 -> {99};
99 -> {100}; 99 -> {100};
100 -> {101}; 100 -> {106};
101 -> {102}; 100 -> {101} [style=dotted];
102 -> {109}; 101 -> {102} [style=dotted];
102 -> {103} [style=dotted]; 102 -> {103} [style=dotted];
103 -> {104} [style=dotted]; 103 -> {104} [style=dotted];
104 -> {105} [style=dotted]; 104 -> {105} [style=dotted];
105 -> {106} [style=dotted]; 105 -> {98} [style=dotted];
106 -> {107} [style=dotted]; 106 -> {107};
107 -> {108} [style=dotted]; 107 -> {108};
108 -> {100} [style=dotted];
109 -> {110};
110 -> {111};
subgraph cluster_33 { subgraph cluster_33 {
color=red color=red
112 [label="Enter function testDoWhileTrue" style="filled" fillcolor=red]; 109 [label="Enter function testDoWhileTrue" style="filled" fillcolor=red];
subgraph cluster_34 { subgraph cluster_34 {
color=blue color=blue
113 [label="Enter do-while loop"]; 110 [label="Enter do-while loop"];
subgraph cluster_35 { subgraph cluster_35 {
color=blue color=blue
114 [label="Enter loop block"]; 111 [label="Enter loop block"];
subgraph cluster_36 { subgraph cluster_36 {
color=blue color=blue
115 [label="Enter block"]; 112 [label="Enter block"];
116 [label="Const: Int(1)"]; 113 [label="Const: Int(1)"];
117 [label="Exit block"]; 114 [label="Exit block"];
} }
118 [label="Exit loop block"]; 115 [label="Exit loop block"];
} }
subgraph cluster_37 { subgraph cluster_37 {
color=blue color=blue
119 [label="Enter loop condition"]; 116 [label="Enter loop condition"];
120 [label="Const: Boolean(true)"]; 117 [label="Const: Boolean(true)"];
121 [label="Exit loop condition"]; 118 [label="Exit loop condition"];
} }
122 [label="Stub" style="filled" fillcolor=gray]; 119 [label="Exit do-whileloop" style="filled" fillcolor=gray];
123 [label="Exit do-whileloop" style="filled" fillcolor=gray];
} }
124 [label="Const: Int(1)" style="filled" fillcolor=gray]; 120 [label="Const: Int(1)" style="filled" fillcolor=gray];
125 [label="Exit function testDoWhileTrue" style="filled" fillcolor=red style="filled" fillcolor=gray]; 121 [label="Exit function testDoWhileTrue" style="filled" fillcolor=red style="filled" fillcolor=gray];
} }
109 -> {110};
110 -> {111};
111 -> {112};
112 -> {113}; 112 -> {113};
113 -> {114}; 113 -> {114};
114 -> {115}; 114 -> {115};
115 -> {116}; 115 -> {116};
116 -> {117}; 116 -> {117};
117 -> {118}; 117 -> {118};
118 -> {119}; 118 -> {111};
119 -> {120}; 118 -> {119} [style=dotted];
120 -> {121}; 119 -> {120} [style=dotted];
121 -> {114}; 120 -> {121} [style=dotted];
121 -> {122} [style=dotted];
122 -> {123} [style=dotted];
123 -> {124} [style=dotted];
124 -> {125} [style=dotted];
subgraph cluster_38 { subgraph cluster_38 {
color=red color=red
126 [label="Enter function testDoWhileTrueWithBreak" style="filled" fillcolor=red]; 122 [label="Enter function testDoWhileTrueWithBreak" style="filled" fillcolor=red];
subgraph cluster_39 { subgraph cluster_39 {
color=blue color=blue
127 [label="Enter do-while loop"]; 123 [label="Enter do-while loop"];
subgraph cluster_40 { subgraph cluster_40 {
color=blue color=blue
128 [label="Enter loop block"]; 124 [label="Enter loop block"];
subgraph cluster_41 { subgraph cluster_41 {
color=blue color=blue
129 [label="Enter block"]; 125 [label="Enter block"];
subgraph cluster_42 { subgraph cluster_42 {
color=blue color=blue
130 [label="Enter when"]; 126 [label="Enter when"];
subgraph cluster_43 { subgraph cluster_43 {
color=blue color=blue
131 [label="Enter when branch condition "]; 127 [label="Enter when branch condition "];
132 [label="Access variable R|<local>/b|"]; 128 [label="Access variable R|<local>/b|"];
133 [label="Exit when branch condition"]; 129 [label="Exit when branch condition"];
} }
134 [label="Synthetic else branch"]; 130 [label="Synthetic else branch"];
135 [label="Enter when branch result"]; 131 [label="Enter when branch result"];
subgraph cluster_44 { subgraph cluster_44 {
color=blue color=blue
136 [label="Enter block"]; 132 [label="Enter block"];
137 [label="Jump: break@@@[Boolean(true)] "]; 133 [label="Jump: break@@@[Boolean(true)] "];
138 [label="Stub" style="filled" fillcolor=gray]; 134 [label="Stub" style="filled" fillcolor=gray];
139 [label="Exit block" style="filled" fillcolor=gray]; 135 [label="Exit block" style="filled" fillcolor=gray];
} }
140 [label="Exit when branch result" style="filled" fillcolor=gray]; 136 [label="Exit when branch result" style="filled" fillcolor=gray];
141 [label="Exit when"]; 137 [label="Exit when"];
} }
142 [label="Exit block"]; 138 [label="Exit block"];
} }
143 [label="Exit loop block"]; 139 [label="Exit loop block"];
} }
subgraph cluster_45 { subgraph cluster_45 {
color=blue color=blue
144 [label="Enter loop condition"]; 140 [label="Enter loop condition"];
145 [label="Const: Boolean(true)"]; 141 [label="Const: Boolean(true)"];
146 [label="Exit loop condition"]; 142 [label="Exit loop condition"];
} }
147 [label="Stub" style="filled" fillcolor=gray]; 143 [label="Exit do-whileloop"];
148 [label="Exit do-whileloop"];
} }
149 [label="Const: Int(1)"]; 144 [label="Const: Int(1)"];
150 [label="Exit function testDoWhileTrueWithBreak" style="filled" fillcolor=red]; 145 [label="Exit function testDoWhileTrueWithBreak" style="filled" fillcolor=red];
} }
122 -> {123};
123 -> {124};
124 -> {125};
125 -> {126};
126 -> {127}; 126 -> {127};
127 -> {128}; 127 -> {128};
128 -> {129}; 128 -> {129};
129 -> {130}; 129 -> {131 130};
130 -> {131}; 130 -> {137};
131 -> {132}; 131 -> {132};
132 -> {133}; 132 -> {133};
133 -> {135 134}; 133 -> {143};
134 -> {141}; 133 -> {134} [style=dotted];
135 -> {136}; 134 -> {135} [style=dotted];
136 -> {137}; 135 -> {136} [style=dotted];
137 -> {148}; 136 -> {137} [style=dotted];
137 -> {138} [style=dotted]; 137 -> {138};
138 -> {139} [style=dotted]; 138 -> {139};
139 -> {140} [style=dotted]; 139 -> {140};
140 -> {141} [style=dotted]; 140 -> {141};
141 -> {142}; 141 -> {142};
142 -> {143}; 142 -> {124};
142 -> {143} [style=dotted];
143 -> {144}; 143 -> {144};
144 -> {145}; 144 -> {145};
145 -> {146};
146 -> {128};
146 -> {147} [style=dotted];
147 -> {148} [style=dotted];
148 -> {149};
149 -> {150};
subgraph cluster_46 { subgraph cluster_46 {
color=red color=red
151 [label="Enter function testDoWhileFalse" style="filled" fillcolor=red]; 146 [label="Enter function testDoWhileFalse" style="filled" fillcolor=red];
subgraph cluster_47 { subgraph cluster_47 {
color=blue color=blue
152 [label="Enter do-while loop"]; 147 [label="Enter do-while loop"];
subgraph cluster_48 { subgraph cluster_48 {
color=blue color=blue
153 [label="Enter loop block"]; 148 [label="Enter loop block"];
subgraph cluster_49 { subgraph cluster_49 {
color=blue color=blue
154 [label="Enter block"]; 149 [label="Enter block"];
155 [label="Const: Int(1)"]; 150 [label="Const: Int(1)"];
156 [label="Exit block"]; 151 [label="Exit block"];
} }
157 [label="Exit loop block"]; 152 [label="Exit loop block"];
} }
subgraph cluster_50 { subgraph cluster_50 {
color=blue color=blue
158 [label="Enter loop condition"]; 153 [label="Enter loop condition"];
159 [label="Const: Boolean(false)"]; 154 [label="Const: Boolean(false)"];
160 [label="Exit loop condition"]; 155 [label="Exit loop condition"];
} }
161 [label="Exit do-whileloop"]; 156 [label="Exit do-whileloop"];
} }
162 [label="Const: Int(1)"]; 157 [label="Const: Int(1)"];
163 [label="Exit function testDoWhileFalse" style="filled" fillcolor=red]; 158 [label="Exit function testDoWhileFalse" style="filled" fillcolor=red];
} }
164 [label="Stub" style="filled" fillcolor=gray];
146 -> {147};
147 -> {148};
148 -> {149};
149 -> {150};
150 -> {151};
151 -> {152}; 151 -> {152};
152 -> {153}; 152 -> {153};
153 -> {154}; 153 -> {154};
154 -> {155}; 154 -> {155};
155 -> {156}; 155 -> {156};
155 -> {148} [style=dotted];
156 -> {157}; 156 -> {157};
157 -> {158}; 157 -> {158};
158 -> {159};
159 -> {160};
160 -> {161};
160 -> {164} [style=dotted];
161 -> {162};
162 -> {163};
164 -> {153} [style=dotted];
} }
+11 -13
View File
@@ -229,12 +229,11 @@ digraph tryCatch_kt {
} }
92 [label="Exit loop block"]; 92 [label="Exit loop block"];
} }
93 [label="Stub" style="filled" fillcolor=gray]; 93 [label="Exit whileloop"];
94 [label="Exit whileloop"];
} }
95 [label="Const: Int(3)"]; 94 [label="Const: Int(3)"];
96 [label="Variable declaration: lval z: R|kotlin/Int|"]; 95 [label="Variable declaration: lval z: R|kotlin/Int|"];
97 [label="Exit function test_3" style="filled" fillcolor=red]; 96 [label="Exit function test_3" style="filled" fillcolor=red];
} }
37 -> {38}; 37 -> {38};
@@ -246,7 +245,7 @@ digraph tryCatch_kt {
42 -> {43}; 42 -> {43};
43 -> {44}; 43 -> {44};
44 -> {45}; 44 -> {45};
45 -> {97 82 76 46}; 45 -> {96 82 76 46};
46 -> {47}; 46 -> {47};
47 -> {48}; 47 -> {48};
48 -> {49}; 48 -> {49};
@@ -255,7 +254,7 @@ digraph tryCatch_kt {
51 -> {58}; 51 -> {58};
52 -> {53}; 52 -> {53};
53 -> {54}; 53 -> {54};
54 -> {97}; 54 -> {96};
54 -> {55} [style=dotted]; 54 -> {55} [style=dotted];
55 -> {56} [style=dotted]; 55 -> {56} [style=dotted];
56 -> {57} [style=dotted]; 56 -> {57} [style=dotted];
@@ -271,7 +270,7 @@ digraph tryCatch_kt {
66 -> {73}; 66 -> {73};
67 -> {68}; 67 -> {68};
68 -> {69}; 68 -> {69};
69 -> {94}; 69 -> {93};
69 -> {70} [style=dotted]; 69 -> {70} [style=dotted];
70 -> {71} [style=dotted]; 70 -> {71} [style=dotted];
71 -> {72} [style=dotted]; 71 -> {72} [style=dotted];
@@ -279,14 +278,14 @@ digraph tryCatch_kt {
73 -> {74}; 73 -> {74};
74 -> {75}; 74 -> {75};
75 -> {88}; 75 -> {88};
76 -> {97 77}; 76 -> {96 77};
77 -> {78}; 77 -> {78};
78 -> {94}; 78 -> {93};
78 -> {79} [style=dotted]; 78 -> {79} [style=dotted];
79 -> {80} [style=dotted]; 79 -> {80} [style=dotted];
80 -> {81} [style=dotted]; 80 -> {81} [style=dotted];
81 -> {88} [style=dotted]; 81 -> {88} [style=dotted];
82 -> {97 83}; 82 -> {96 83};
83 -> {84}; 83 -> {84};
84 -> {38}; 84 -> {38};
84 -> {85} [style=dotted]; 84 -> {85} [style=dotted];
@@ -298,9 +297,8 @@ digraph tryCatch_kt {
90 -> {91}; 90 -> {91};
91 -> {92}; 91 -> {92};
92 -> {39}; 92 -> {39};
93 -> {94} [style=dotted]; 93 -> {94};
94 -> {95}; 94 -> {95};
95 -> {96}; 95 -> {96};
96 -> {97};
} }
@@ -289,14 +289,14 @@ digraph booleanOperators_kt {
101 [label="Enter when branch condition "]; 101 [label="Enter when branch condition "];
subgraph cluster_26 { subgraph cluster_26 {
color=blue color=blue
102 [label="Enter ||"]; 102 [label="Enter &&"];
103 [label="Access variable R|<local>/x|"]; 103 [label="Access variable R|<local>/x|"];
104 [label="Const: Null(null)"]; 104 [label="Type operator: x is A"];
105 [label="Operator !="]; 105 [label="Exit left part of &&"];
106 [label="Exit left part of ||"]; 106 [label="Enter right part of &&"];
107 [label="Enter right part of ||"]; 107 [label="Access variable R|<local>/x|"];
108 [label="Const: Boolean(false)"]; 108 [label="Function call: R|<local>/x|.R|/A.bool|()"];
109 [label="Exit ||"]; 109 [label="Exit &&"];
} }
110 [label="Exit when branch condition"]; 110 [label="Exit when branch condition"];
} }
@@ -306,7 +306,7 @@ digraph booleanOperators_kt {
color=blue color=blue
113 [label="Enter block"]; 113 [label="Enter block"];
114 [label="Access variable R|<local>/x|"]; 114 [label="Access variable R|<local>/x|"];
115 [label="Function call: R|<local>/x|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()"]; 115 [label="Function call: R|<local>/x|.R|/A.foo|()"];
116 [label="Exit block"]; 116 [label="Exit block"];
} }
117 [label="Exit when branch result"]; 117 [label="Exit when branch result"];
@@ -321,8 +321,8 @@ digraph booleanOperators_kt {
102 -> {103}; 102 -> {103};
103 -> {104}; 103 -> {104};
104 -> {105}; 104 -> {105};
105 -> {106}; 105 -> {109 106};
106 -> {109 107}; 106 -> {107};
107 -> {108}; 107 -> {108};
108 -> {109}; 108 -> {109};
109 -> {110}; 109 -> {110};
@@ -345,33 +345,24 @@ digraph booleanOperators_kt {
subgraph cluster_30 { subgraph cluster_30 {
color=blue color=blue
122 [label="Enter when branch condition "]; 122 [label="Enter when branch condition "];
123 [label="Access variable R|<local>/x|"];
124 [label="Type operator: x !is A"];
125 [label="Function call: (R|<local>/x| !is R|A|).R|kotlin/Boolean.not|()"];
126 [label="Exit when branch condition"];
}
127 [label="Synthetic else branch"];
128 [label="Enter when branch result"];
subgraph cluster_31 { subgraph cluster_31 {
color=blue color=blue
123 [label="Enter ||"]; 129 [label="Enter block"];
124 [label="Const: Boolean(false)"]; 130 [label="Access variable R|<local>/x|"];
125 [label="Exit left part of ||"]; 131 [label="Function call: R|<local>/x|.R|/A.foo|()"];
126 [label="Enter right part of ||"]; 132 [label="Exit block"];
127 [label="Access variable R|<local>/x|"];
128 [label="Const: Null(null)"];
129 [label="Operator !="];
130 [label="Stub" style="filled" fillcolor=gray];
131 [label="Exit ||"];
} }
132 [label="Exit when branch condition"]; 133 [label="Exit when branch result"];
134 [label="Exit when"];
} }
133 [label="Synthetic else branch"]; 135 [label="Exit function test_6" style="filled" fillcolor=red];
134 [label="Enter when branch result"];
subgraph cluster_32 {
color=blue
135 [label="Enter block"];
136 [label="Access variable R|<local>/x|"];
137 [label="Function call: R|<local>/x|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()"];
138 [label="Exit block"];
}
139 [label="Exit when branch result"];
140 [label="Exit when"];
}
141 [label="Exit function test_6" style="filled" fillcolor=red];
} }
120 -> {121}; 120 -> {121};
@@ -380,124 +371,466 @@ digraph booleanOperators_kt {
123 -> {124}; 123 -> {124};
124 -> {125}; 124 -> {125};
125 -> {126}; 125 -> {126};
125 -> {130} [style=dotted]; 126 -> {128 127};
126 -> {127}; 127 -> {134};
127 -> {128};
128 -> {129}; 128 -> {129};
129 -> {131}; 129 -> {130};
130 -> {131} [style=dotted]; 130 -> {131};
131 -> {132}; 131 -> {132};
132 -> {134 133}; 132 -> {133};
133 -> {140}; 133 -> {134};
134 -> {135}; 134 -> {135};
135 -> {136};
subgraph cluster_32 {
color=red
136 [label="Enter function test_7" style="filled" fillcolor=red];
subgraph cluster_33 {
color=blue
137 [label="Enter when"];
subgraph cluster_34 {
color=blue
138 [label="Enter when branch condition "];
subgraph cluster_35 {
color=blue
139 [label="Enter ||"];
140 [label="Access variable R|<local>/x|"];
141 [label="Type operator: x is A"];
142 [label="Exit left part of ||"];
143 [label="Enter right part of ||"];
144 [label="Const: Boolean(false)"];
145 [label="Exit ||"];
}
146 [label="Exit when branch condition"];
}
147 [label="Synthetic else branch"];
148 [label="Enter when branch result"];
subgraph cluster_36 {
color=blue
149 [label="Enter block"];
150 [label="Access variable R|<local>/x|"];
151 [label="Function call: R|<local>/x|.<Unresolved name: foo>#()"];
152 [label="Exit block"];
}
153 [label="Exit when branch result"];
154 [label="Exit when"];
}
155 [label="Exit function test_7" style="filled" fillcolor=red];
}
136 -> {137}; 136 -> {137};
137 -> {138}; 137 -> {138};
138 -> {139}; 138 -> {139};
139 -> {140}; 139 -> {140};
140 -> {141}; 140 -> {141};
141 -> {142};
subgraph cluster_33 { 142 -> {145 143};
color=red
142 [label="Enter function test_7" style="filled" fillcolor=red];
subgraph cluster_34 {
color=blue
143 [label="Enter when"];
subgraph cluster_35 {
color=blue
144 [label="Enter when branch condition "];
subgraph cluster_36 {
color=blue
145 [label="Enter &&"];
146 [label="Access variable R|<local>/x|"];
147 [label="Type operator: x is A"];
148 [label="Exit left part of &&"];
149 [label="Enter right part of &&"];
150 [label="Access variable R|<local>/x|"];
151 [label="Function call: R|<local>/x|.R|/A.bool|()"];
152 [label="Exit &&"];
}
153 [label="Exit when branch condition"];
}
154 [label="Synthetic else branch"];
155 [label="Enter when branch result"];
subgraph cluster_37 {
color=blue
156 [label="Enter block"];
157 [label="Access variable R|<local>/x|"];
158 [label="Function call: R|<local>/x|.R|/A.foo|()"];
159 [label="Exit block"];
}
160 [label="Exit when branch result"];
161 [label="Exit when"];
}
162 [label="Exit function test_7" style="filled" fillcolor=red];
}
142 -> {143};
143 -> {144}; 143 -> {144};
144 -> {145}; 144 -> {145};
145 -> {146}; 145 -> {146};
146 -> {147}; 146 -> {148 147};
147 -> {148}; 147 -> {154};
148 -> {152 149}; 148 -> {149};
149 -> {150}; 149 -> {150};
150 -> {151}; 150 -> {151};
151 -> {152}; 151 -> {152};
152 -> {153}; 152 -> {153};
153 -> {155 154}; 153 -> {154};
154 -> {161}; 154 -> {155};
155 -> {156};
subgraph cluster_37 {
color=red
156 [label="Enter function test_8" style="filled" fillcolor=red];
subgraph cluster_38 {
color=blue
157 [label="Enter when"];
subgraph cluster_39 {
color=blue
158 [label="Enter when branch condition "];
subgraph cluster_40 {
color=blue
159 [label="Enter ||"];
160 [label="Const: Boolean(false)"];
161 [label="Exit left part of ||"];
162 [label="Enter right part of ||"];
163 [label="Access variable R|<local>/x|"];
164 [label="Type operator: x is A"];
165 [label="Exit ||"];
}
166 [label="Exit when branch condition"];
}
167 [label="Synthetic else branch"];
168 [label="Enter when branch result"];
subgraph cluster_41 {
color=blue
169 [label="Enter block"];
170 [label="Access variable R|<local>/x|"];
171 [label="Function call: R|<local>/x|.<Unresolved name: foo>#()"];
172 [label="Exit block"];
}
173 [label="Exit when branch result"];
174 [label="Exit when"];
}
175 [label="Exit function test_8" style="filled" fillcolor=red];
}
156 -> {157}; 156 -> {157};
157 -> {158}; 157 -> {158};
158 -> {159}; 158 -> {159};
159 -> {160}; 159 -> {160};
160 -> {161}; 160 -> {161};
161 -> {162}; 161 -> {162};
161 -> {165} [style=dotted];
subgraph cluster_38 { 162 -> {163};
color=red
163 [label="Enter function test_8" style="filled" fillcolor=red];
subgraph cluster_39 {
color=blue
164 [label="Enter when"];
subgraph cluster_40 {
color=blue
165 [label="Enter when branch condition "];
166 [label="Access variable R|<local>/x|"];
167 [label="Type operator: x !is A"];
168 [label="Function call: (R|<local>/x| !is R|A|).R|kotlin/Boolean.not|()"];
169 [label="Exit when branch condition"];
}
170 [label="Synthetic else branch"];
171 [label="Enter when branch result"];
subgraph cluster_41 {
color=blue
172 [label="Enter block"];
173 [label="Access variable R|<local>/x|"];
174 [label="Function call: R|<local>/x|.R|/A.foo|()"];
175 [label="Exit block"];
}
176 [label="Exit when branch result"];
177 [label="Exit when"];
}
178 [label="Exit function test_8" style="filled" fillcolor=red];
}
163 -> {164}; 163 -> {164};
164 -> {165}; 164 -> {165};
165 -> {166}; 165 -> {166};
166 -> {167}; 166 -> {168 167};
167 -> {168}; 167 -> {174};
168 -> {169}; 168 -> {169};
169 -> {171 170}; 169 -> {170};
170 -> {177}; 170 -> {171};
171 -> {172}; 171 -> {172};
172 -> {173}; 172 -> {173};
173 -> {174}; 173 -> {174};
174 -> {175}; 174 -> {175};
175 -> {176};
subgraph cluster_42 {
color=red
176 [label="Enter function test_9" style="filled" fillcolor=red];
subgraph cluster_43 {
color=blue
177 [label="Enter when"];
subgraph cluster_44 {
color=blue
178 [label="Enter when branch condition "];
subgraph cluster_45 {
color=blue
179 [label="Enter ||"];
180 [label="Access variable R|<local>/x|"];
181 [label="Type operator: x is A"];
182 [label="Exit left part of ||"];
183 [label="Enter right part of ||"];
184 [label="Const: Boolean(true)"];
185 [label="Exit ||"];
}
186 [label="Exit when branch condition"];
}
187 [label="Synthetic else branch"];
188 [label="Enter when branch result"];
subgraph cluster_46 {
color=blue
189 [label="Enter block"];
190 [label="Access variable R|<local>/x|"];
191 [label="Function call: R|<local>/x|.<Unresolved name: foo>#()"];
192 [label="Exit block"];
}
193 [label="Exit when branch result"];
194 [label="Exit when"];
}
195 [label="Exit function test_9" style="filled" fillcolor=red];
}
176 -> {177}; 176 -> {177};
177 -> {178}; 177 -> {178};
178 -> {179};
179 -> {180};
180 -> {181};
181 -> {182};
182 -> {185 183};
183 -> {184};
184 -> {185};
185 -> {186};
186 -> {188 187};
187 -> {194};
188 -> {189};
189 -> {190};
190 -> {191};
191 -> {192};
192 -> {193};
193 -> {194};
194 -> {195};
subgraph cluster_47 {
color=red
196 [label="Enter function test_10" style="filled" fillcolor=red];
subgraph cluster_48 {
color=blue
197 [label="Enter when"];
subgraph cluster_49 {
color=blue
198 [label="Enter when branch condition "];
subgraph cluster_50 {
color=blue
199 [label="Enter ||"];
200 [label="Const: Boolean(true)"];
201 [label="Exit left part of ||"];
202 [label="Enter right part of ||" style="filled" fillcolor=gray];
203 [label="Access variable R|<local>/x|" style="filled" fillcolor=gray];
204 [label="Type operator: x is A" style="filled" fillcolor=gray];
205 [label="Exit ||"];
}
206 [label="Exit when branch condition"];
}
207 [label="Synthetic else branch"];
208 [label="Enter when branch result"];
subgraph cluster_51 {
color=blue
209 [label="Enter block"];
210 [label="Access variable R|<local>/x|"];
211 [label="Function call: R|<local>/x|.<Unresolved name: foo>#()"];
212 [label="Exit block"];
}
213 [label="Exit when branch result"];
214 [label="Exit when"];
}
215 [label="Exit function test_10" style="filled" fillcolor=red];
}
196 -> {197};
197 -> {198};
198 -> {199};
199 -> {200};
200 -> {201};
201 -> {205};
201 -> {202} [style=dotted];
202 -> {203} [style=dotted];
203 -> {204} [style=dotted];
204 -> {205} [style=dotted];
205 -> {206};
206 -> {208 207};
207 -> {214};
208 -> {209};
209 -> {210};
210 -> {211};
211 -> {212};
212 -> {213};
213 -> {214};
214 -> {215};
subgraph cluster_52 {
color=red
216 [label="Enter function test_11" style="filled" fillcolor=red];
subgraph cluster_53 {
color=blue
217 [label="Enter when"];
subgraph cluster_54 {
color=blue
218 [label="Enter when branch condition "];
subgraph cluster_55 {
color=blue
219 [label="Enter &&"];
220 [label="Const: Boolean(false)"];
221 [label="Exit left part of &&"];
222 [label="Enter right part of &&" style="filled" fillcolor=gray];
223 [label="Access variable R|<local>/x|" style="filled" fillcolor=gray];
224 [label="Type operator: x is A" style="filled" fillcolor=gray];
225 [label="Exit &&"];
}
226 [label="Exit when branch condition"];
}
227 [label="Synthetic else branch"];
228 [label="Enter when branch result"];
subgraph cluster_56 {
color=blue
229 [label="Enter block"];
230 [label="Access variable R|<local>/x|"];
231 [label="Function call: R|<local>/x|.R|/A.foo|()"];
232 [label="Exit block"];
}
233 [label="Exit when branch result"];
234 [label="Exit when"];
}
235 [label="Exit function test_11" style="filled" fillcolor=red];
}
216 -> {217};
217 -> {218};
218 -> {219};
219 -> {220};
220 -> {221};
221 -> {225};
221 -> {222} [style=dotted];
222 -> {223} [style=dotted];
223 -> {224} [style=dotted];
224 -> {225} [style=dotted];
225 -> {226};
226 -> {228 227};
227 -> {234};
228 -> {229};
229 -> {230};
230 -> {231};
231 -> {232};
232 -> {233};
233 -> {234};
234 -> {235};
subgraph cluster_57 {
color=red
236 [label="Enter function test_12" style="filled" fillcolor=red];
subgraph cluster_58 {
color=blue
237 [label="Enter when"];
subgraph cluster_59 {
color=blue
238 [label="Enter when branch condition "];
subgraph cluster_60 {
color=blue
239 [label="Enter &&"];
240 [label="Access variable R|<local>/x|"];
241 [label="Type operator: x is A"];
242 [label="Exit left part of &&"];
243 [label="Enter right part of &&"];
244 [label="Const: Boolean(false)"];
245 [label="Exit &&"];
}
246 [label="Exit when branch condition"];
}
247 [label="Synthetic else branch"];
248 [label="Enter when branch result"];
subgraph cluster_61 {
color=blue
249 [label="Enter block"];
250 [label="Access variable R|<local>/x|"];
251 [label="Function call: R|<local>/x|.R|/A.foo|()"];
252 [label="Exit block"];
}
253 [label="Exit when branch result"];
254 [label="Exit when"];
}
255 [label="Exit function test_12" style="filled" fillcolor=red];
}
236 -> {237};
237 -> {238};
238 -> {239};
239 -> {240};
240 -> {241};
241 -> {242};
242 -> {245 243};
243 -> {244};
244 -> {245};
245 -> {246};
246 -> {248 247};
247 -> {254};
248 -> {249};
249 -> {250};
250 -> {251};
251 -> {252};
252 -> {253};
253 -> {254};
254 -> {255};
subgraph cluster_62 {
color=red
256 [label="Enter function test_13" style="filled" fillcolor=red];
subgraph cluster_63 {
color=blue
257 [label="Enter when"];
subgraph cluster_64 {
color=blue
258 [label="Enter when branch condition "];
subgraph cluster_65 {
color=blue
259 [label="Enter &&"];
260 [label="Const: Boolean(true)"];
261 [label="Exit left part of &&"];
262 [label="Enter right part of &&"];
263 [label="Access variable R|<local>/x|"];
264 [label="Type operator: x is A"];
265 [label="Exit &&"];
}
266 [label="Exit when branch condition"];
}
267 [label="Synthetic else branch"];
268 [label="Enter when branch result"];
subgraph cluster_66 {
color=blue
269 [label="Enter block"];
270 [label="Access variable R|<local>/x|"];
271 [label="Function call: R|<local>/x|.R|/A.foo|()"];
272 [label="Exit block"];
}
273 [label="Exit when branch result"];
274 [label="Exit when"];
}
275 [label="Exit function test_13" style="filled" fillcolor=red];
}
256 -> {257};
257 -> {258};
258 -> {259};
259 -> {260};
260 -> {261};
261 -> {262};
261 -> {265} [style=dotted];
262 -> {263};
263 -> {264};
264 -> {265};
265 -> {266};
266 -> {268 267};
267 -> {274};
268 -> {269};
269 -> {270};
270 -> {271};
271 -> {272};
272 -> {273};
273 -> {274};
274 -> {275};
subgraph cluster_67 {
color=red
276 [label="Enter function test_14" style="filled" fillcolor=red];
subgraph cluster_68 {
color=blue
277 [label="Enter when"];
subgraph cluster_69 {
color=blue
278 [label="Enter when branch condition "];
subgraph cluster_70 {
color=blue
279 [label="Enter &&"];
280 [label="Access variable R|<local>/x|"];
281 [label="Type operator: x is A"];
282 [label="Exit left part of &&"];
283 [label="Enter right part of &&"];
284 [label="Const: Boolean(false)"];
285 [label="Exit &&"];
}
286 [label="Exit when branch condition"];
}
287 [label="Synthetic else branch"];
288 [label="Enter when branch result"];
subgraph cluster_71 {
color=blue
289 [label="Enter block"];
290 [label="Access variable R|<local>/x|"];
291 [label="Function call: R|<local>/x|.R|/A.foo|()"];
292 [label="Exit block"];
}
293 [label="Exit when branch result"];
294 [label="Exit when"];
}
295 [label="Exit function test_14" style="filled" fillcolor=red];
}
276 -> {277};
277 -> {278};
278 -> {279};
279 -> {280};
280 -> {281};
281 -> {282};
282 -> {285 283};
283 -> {284};
284 -> {285};
285 -> {286};
286 -> {288 287};
287 -> {294};
288 -> {289};
289 -> {290};
290 -> {291};
291 -> {292};
292 -> {293};
293 -> {294};
294 -> {295};
} }
@@ -41,26 +41,68 @@ fun test_4(x: Any) {
x.<!UNRESOLVED_REFERENCE!>length<!> x.<!UNRESOLVED_REFERENCE!>length<!>
} }
fun test_5(x: A?) { fun test_5(x: Any) {
if (x != null || false) {
x.<!INAPPLICABLE_CANDIDATE!>foo<!>()
}
}
fun test_6(x: A?) {
if (false || x != null) {
x.<!INAPPLICABLE_CANDIDATE!>foo<!>()
}
}
fun test_7(x: Any) {
if (x is A && x.bool()) { if (x is A && x.bool()) {
x.foo() x.foo()
} }
} }
fun test_8(x: Any) { fun test_6(x: Any) {
if ((x !is A).not()) { if ((x !is A).not()) {
x.foo() x.foo()
} }
} }
// || and const
fun test_7(x: Any) {
if (x is A || false) {
// TODO: should be smartcast
x.<!UNRESOLVED_REFERENCE!>foo<!>()
}
}
fun test_8(x: Any) {
if (false || x is A) {
// TODO: should be smartcast
x.<!UNRESOLVED_REFERENCE!>foo<!>()
}
}
fun test_9(x: Any) {
if (x is A || true) {
x.<!UNRESOLVED_REFERENCE!>foo<!>()
}
}
fun test_10(x: Any) {
if (true || x is A) {
x.<!UNRESOLVED_REFERENCE!>foo<!>()
}
}
// && and const
fun test_11(x: Any, b: Boolean) {
if (false && x is A) {
x.foo()
}
}
fun test_12(x: Any, b: Boolean) {
if (x is A && false) {
x.foo()
}
}
fun test_13(x: Any, b: Boolean) {
if (true && x is A) {
x.foo()
}
}
fun test_14(x: Any, b: Boolean) {
if (x is A && false) {
x.foo()
}
}
@@ -50,23 +50,7 @@ FILE: booleanOperators.kt
R|<local>/x|.<Unresolved name: length># R|<local>/x|.<Unresolved name: length>#
} }
public final fun test_5(x: R|A?|): R|kotlin/Unit| { public final fun test_5(x: R|kotlin/Any|): R|kotlin/Unit| {
when () {
!=(R|<local>/x|, Null(null)) || Boolean(false) -> {
R|<local>/x|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()
}
}
}
public final fun test_6(x: R|A?|): R|kotlin/Unit| {
when () {
Boolean(false) || !=(R|<local>/x|, Null(null)) -> {
R|<local>/x|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()
}
}
}
public final fun test_7(x: R|kotlin/Any|): R|kotlin/Unit| {
when () { when () {
(R|<local>/x| is R|A|) && R|<local>/x|.R|/A.bool|() -> { (R|<local>/x| is R|A|) && R|<local>/x|.R|/A.bool|() -> {
R|<local>/x|.R|/A.foo|() R|<local>/x|.R|/A.foo|()
@@ -74,7 +58,7 @@ FILE: booleanOperators.kt
} }
} }
public final fun test_8(x: R|kotlin/Any|): R|kotlin/Unit| { public final fun test_6(x: R|kotlin/Any|): R|kotlin/Unit| {
when () { when () {
(R|<local>/x| !is R|A|).R|kotlin/Boolean.not|() -> { (R|<local>/x| !is R|A|).R|kotlin/Boolean.not|() -> {
R|<local>/x|.R|/A.foo|() R|<local>/x|.R|/A.foo|()
@@ -82,3 +66,67 @@ FILE: booleanOperators.kt
} }
} }
public final fun test_7(x: R|kotlin/Any|): R|kotlin/Unit| {
when () {
(R|<local>/x| is R|A|) || Boolean(false) -> {
R|<local>/x|.<Unresolved name: foo>#()
}
}
}
public final fun test_8(x: R|kotlin/Any|): R|kotlin/Unit| {
when () {
Boolean(false) || (R|<local>/x| is R|A|) -> {
R|<local>/x|.<Unresolved name: foo>#()
}
}
}
public final fun test_9(x: R|kotlin/Any|): R|kotlin/Unit| {
when () {
(R|<local>/x| is R|A|) || Boolean(true) -> {
R|<local>/x|.<Unresolved name: foo>#()
}
}
}
public final fun test_10(x: R|kotlin/Any|): R|kotlin/Unit| {
when () {
Boolean(true) || (R|<local>/x| is R|A|) -> {
R|<local>/x|.<Unresolved name: foo>#()
}
}
}
public final fun test_11(x: R|kotlin/Any|, b: R|kotlin/Boolean|): R|kotlin/Unit| {
when () {
Boolean(false) && (R|<local>/x| is R|A|) -> {
R|<local>/x|.R|/A.foo|()
}
}
}
public final fun test_12(x: R|kotlin/Any|, b: R|kotlin/Boolean|): R|kotlin/Unit| {
when () {
(R|<local>/x| is R|A|) && Boolean(false) -> {
R|<local>/x|.R|/A.foo|()
}
}
}
public final fun test_13(x: R|kotlin/Any|, b: R|kotlin/Boolean|): R|kotlin/Unit| {
when () {
Boolean(true) && (R|<local>/x| is R|A|) -> {
R|<local>/x|.R|/A.foo|()
}
}
}
public final fun test_14(x: R|kotlin/Any|, b: R|kotlin/Boolean|): R|kotlin/Unit| {
when () {
(R|<local>/x| is R|A|) && Boolean(false) -> {
R|<local>/x|.R|/A.foo|()
}
}
}
@@ -0,0 +1,503 @@
digraph booleanOperators_kt {
graph [splines=ortho nodesep=3]
node [shape=box penwidth=2]
edge [penwidth=2]
subgraph cluster_0 {
color=red
0 [label="Enter function foo" style="filled" fillcolor=red];
1 [label="Exit function foo" style="filled" fillcolor=red];
}
0 -> {1};
subgraph cluster_1 {
color=red
2 [label="Enter function bool" style="filled" fillcolor=red];
3 [label="Exit function bool" style="filled" fillcolor=red];
}
2 -> {3};
subgraph cluster_2 {
color=red
4 [label="Enter function bar" style="filled" fillcolor=red];
5 [label="Exit function bar" style="filled" fillcolor=red];
}
4 -> {5};
subgraph cluster_3 {
color=red
6 [label="Enter function baz" style="filled" fillcolor=red];
7 [label="Exit function baz" style="filled" fillcolor=red];
}
6 -> {7};
subgraph cluster_4 {
color=red
8 [label="Enter function test_1" style="filled" fillcolor=red];
subgraph cluster_5 {
color=blue
9 [label="Enter when"];
subgraph cluster_6 {
color=blue
10 [label="Enter when branch condition "];
subgraph cluster_7 {
color=blue
11 [label="Enter &&"];
12 [label="Access variable R|<local>/x|"];
13 [label="Type operator: x is B"];
14 [label="Exit left part of &&"];
15 [label="Enter right part of &&"];
16 [label="Access variable R|<local>/x|"];
17 [label="Type operator: x is C"];
18 [label="Exit &&"];
}
19 [label="Exit when branch condition"];
}
20 [label="Synthetic else branch"];
21 [label="Enter when branch result"];
subgraph cluster_8 {
color=blue
22 [label="Enter block"];
23 [label="Access variable R|<local>/x|"];
24 [label="Function call: R|<local>/x|.R|/A.foo|()"];
25 [label="Access variable R|<local>/x|"];
26 [label="Function call: R|<local>/x|.R|/B.bar|()"];
27 [label="Access variable R|<local>/x|"];
28 [label="Function call: R|<local>/x|.R|/C.baz|()"];
29 [label="Exit block"];
}
30 [label="Exit when branch result"];
31 [label="Exit when"];
}
32 [label="Exit function test_1" style="filled" fillcolor=red];
}
8 -> {9};
9 -> {10};
10 -> {11};
11 -> {12};
12 -> {13};
13 -> {14};
14 -> {18 15};
15 -> {16};
16 -> {17};
17 -> {18};
18 -> {19};
19 -> {21 20};
20 -> {31};
21 -> {22};
22 -> {23};
23 -> {24};
24 -> {25};
25 -> {26};
26 -> {27};
27 -> {28};
28 -> {29};
29 -> {30};
30 -> {31};
31 -> {32};
subgraph cluster_9 {
color=red
33 [label="Enter function test_2" style="filled" fillcolor=red];
subgraph cluster_10 {
color=blue
34 [label="Enter when"];
subgraph cluster_11 {
color=blue
35 [label="Enter when branch condition "];
subgraph cluster_12 {
color=blue
36 [label="Enter ||"];
37 [label="Access variable R|<local>/x|"];
38 [label="Type operator: x is B"];
39 [label="Exit left part of ||"];
40 [label="Enter right part of ||"];
41 [label="Access variable R|<local>/x|"];
42 [label="Type operator: x is C"];
43 [label="Exit ||"];
}
44 [label="Exit when branch condition"];
}
45 [label="Synthetic else branch"];
46 [label="Enter when branch result"];
subgraph cluster_13 {
color=blue
47 [label="Enter block"];
48 [label="Access variable R|<local>/x|"];
49 [label="Function call: R|<local>/x|.R|/A.foo|()"];
50 [label="Access variable R|<local>/x|"];
51 [label="Function call: R|<local>/x|.<Unresolved name: bar>#()"];
52 [label="Access variable R|<local>/x|"];
53 [label="Function call: R|<local>/x|.<Unresolved name: baz>#()"];
54 [label="Exit block"];
}
55 [label="Exit when branch result"];
56 [label="Exit when"];
}
57 [label="Exit function test_2" style="filled" fillcolor=red];
}
33 -> {34};
34 -> {35};
35 -> {36};
36 -> {37};
37 -> {38};
38 -> {39};
39 -> {43 40};
40 -> {41};
41 -> {42};
42 -> {43};
43 -> {44};
44 -> {46 45};
45 -> {56};
46 -> {47};
47 -> {48};
48 -> {49};
49 -> {50};
50 -> {51};
51 -> {52};
52 -> {53};
53 -> {54};
54 -> {55};
55 -> {56};
56 -> {57};
subgraph cluster_14 {
color=red
58 [label="Enter function test_3" style="filled" fillcolor=red];
subgraph cluster_15 {
color=blue
59 [label="Enter when"];
subgraph cluster_16 {
color=blue
60 [label="Enter when branch condition "];
61 [label="Access variable R|<local>/x|"];
62 [label="Type operator: x !is A"];
63 [label="Function call: (R|<local>/x| !is R|A|).R|kotlin/Boolean.not|()"];
64 [label="Exit when branch condition"];
}
65 [label="Synthetic else branch"];
66 [label="Enter when branch result"];
subgraph cluster_17 {
color=blue
67 [label="Enter block"];
68 [label="Access variable R|<local>/x|"];
69 [label="Function call: R|<local>/x|.R|/A.foo|()"];
70 [label="Exit block"];
}
71 [label="Exit when branch result"];
72 [label="Exit when"];
}
73 [label="Exit function test_3" style="filled" fillcolor=red];
}
58 -> {59};
59 -> {60};
60 -> {61};
61 -> {62};
62 -> {63};
63 -> {64};
64 -> {66 65};
65 -> {72};
66 -> {67};
67 -> {68};
68 -> {69};
69 -> {70};
70 -> {71};
71 -> {72};
72 -> {73};
subgraph cluster_18 {
color=red
74 [label="Enter function test_4" style="filled" fillcolor=red];
subgraph cluster_19 {
color=blue
75 [label="Enter when"];
subgraph cluster_20 {
color=blue
76 [label="Enter when branch condition "];
subgraph cluster_21 {
color=blue
77 [label="Enter ||"];
78 [label="Access variable R|<local>/x|"];
79 [label="Type operator: x !is String"];
80 [label="Exit left part of ||"];
81 [label="Enter right part of ||"];
82 [label="Access variable R|<local>/x|"];
83 [label="Access variable R|kotlin/String.length|"];
84 [label="Const: Int(0)"];
85 [label="Operator =="];
86 [label="Exit ||"];
}
87 [label="Exit when branch condition"];
}
88 [label="Synthetic else branch"];
89 [label="Enter when branch result"];
subgraph cluster_22 {
color=blue
90 [label="Enter block"];
91 [label="Access variable R|<local>/x|"];
92 [label="Access variable <Unresolved name: length>#"];
93 [label="Exit block"];
}
94 [label="Exit when branch result"];
95 [label="Exit when"];
}
96 [label="Access variable R|<local>/x|"];
97 [label="Access variable <Unresolved name: length>#"];
98 [label="Exit function test_4" style="filled" fillcolor=red];
}
74 -> {75};
75 -> {76};
76 -> {77};
77 -> {78};
78 -> {79};
79 -> {80};
80 -> {86 81};
81 -> {82};
82 -> {83};
83 -> {84};
84 -> {85};
85 -> {86};
86 -> {87};
87 -> {89 88};
88 -> {95};
89 -> {90};
90 -> {91};
91 -> {92};
92 -> {93};
93 -> {94};
94 -> {95};
95 -> {96};
96 -> {97};
97 -> {98};
subgraph cluster_23 {
color=red
99 [label="Enter function test_5" style="filled" fillcolor=red];
subgraph cluster_24 {
color=blue
100 [label="Enter when"];
subgraph cluster_25 {
color=blue
101 [label="Enter when branch condition "];
subgraph cluster_26 {
color=blue
102 [label="Enter ||"];
103 [label="Access variable R|<local>/x|"];
104 [label="Const: Null(null)"];
105 [label="Operator !="];
106 [label="Exit left part of ||"];
107 [label="Enter right part of ||"];
108 [label="Const: Boolean(false)"];
109 [label="Exit ||"];
}
110 [label="Exit when branch condition"];
}
111 [label="Synthetic else branch"];
112 [label="Enter when branch result"];
subgraph cluster_27 {
color=blue
113 [label="Enter block"];
114 [label="Access variable R|<local>/x|"];
115 [label="Function call: R|<local>/x|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()"];
116 [label="Exit block"];
}
117 [label="Exit when branch result"];
118 [label="Exit when"];
}
119 [label="Exit function test_5" style="filled" fillcolor=red];
}
99 -> {100};
100 -> {101};
101 -> {102};
102 -> {103};
103 -> {104};
104 -> {105};
105 -> {106};
106 -> {109 107};
107 -> {108};
108 -> {109};
109 -> {110};
110 -> {112 111};
111 -> {118};
112 -> {113};
113 -> {114};
114 -> {115};
115 -> {116};
116 -> {117};
117 -> {118};
118 -> {119};
subgraph cluster_28 {
color=red
120 [label="Enter function test_6" style="filled" fillcolor=red];
subgraph cluster_29 {
color=blue
121 [label="Enter when"];
subgraph cluster_30 {
color=blue
122 [label="Enter when branch condition "];
subgraph cluster_31 {
color=blue
123 [label="Enter ||"];
124 [label="Const: Boolean(false)"];
125 [label="Exit left part of ||"];
126 [label="Enter right part of ||"];
127 [label="Access variable R|<local>/x|"];
128 [label="Const: Null(null)"];
129 [label="Operator !="];
130 [label="Stub" style="filled" fillcolor=gray];
131 [label="Exit ||"];
}
132 [label="Exit when branch condition"];
}
133 [label="Synthetic else branch"];
134 [label="Enter when branch result"];
subgraph cluster_32 {
color=blue
135 [label="Enter block"];
136 [label="Access variable R|<local>/x|"];
137 [label="Function call: R|<local>/x|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()"];
138 [label="Exit block"];
}
139 [label="Exit when branch result"];
140 [label="Exit when"];
}
141 [label="Exit function test_6" style="filled" fillcolor=red];
}
120 -> {121};
121 -> {122};
122 -> {123};
123 -> {124};
124 -> {125};
125 -> {126};
125 -> {130} [style=dotted];
126 -> {127};
127 -> {128};
128 -> {129};
129 -> {131};
130 -> {131} [style=dotted];
131 -> {132};
132 -> {134 133};
133 -> {140};
134 -> {135};
135 -> {136};
136 -> {137};
137 -> {138};
138 -> {139};
139 -> {140};
140 -> {141};
subgraph cluster_33 {
color=red
142 [label="Enter function test_7" style="filled" fillcolor=red];
subgraph cluster_34 {
color=blue
143 [label="Enter when"];
subgraph cluster_35 {
color=blue
144 [label="Enter when branch condition "];
subgraph cluster_36 {
color=blue
145 [label="Enter &&"];
146 [label="Access variable R|<local>/x|"];
147 [label="Type operator: x is A"];
148 [label="Exit left part of &&"];
149 [label="Enter right part of &&"];
150 [label="Access variable R|<local>/x|"];
151 [label="Function call: R|<local>/x|.R|/A.bool|()"];
152 [label="Exit &&"];
}
153 [label="Exit when branch condition"];
}
154 [label="Synthetic else branch"];
155 [label="Enter when branch result"];
subgraph cluster_37 {
color=blue
156 [label="Enter block"];
157 [label="Access variable R|<local>/x|"];
158 [label="Function call: R|<local>/x|.R|/A.foo|()"];
159 [label="Exit block"];
}
160 [label="Exit when branch result"];
161 [label="Exit when"];
}
162 [label="Exit function test_7" style="filled" fillcolor=red];
}
142 -> {143};
143 -> {144};
144 -> {145};
145 -> {146};
146 -> {147};
147 -> {148};
148 -> {152 149};
149 -> {150};
150 -> {151};
151 -> {152};
152 -> {153};
153 -> {155 154};
154 -> {161};
155 -> {156};
156 -> {157};
157 -> {158};
158 -> {159};
159 -> {160};
160 -> {161};
161 -> {162};
subgraph cluster_38 {
color=red
163 [label="Enter function test_8" style="filled" fillcolor=red];
subgraph cluster_39 {
color=blue
164 [label="Enter when"];
subgraph cluster_40 {
color=blue
165 [label="Enter when branch condition "];
166 [label="Access variable R|<local>/x|"];
167 [label="Type operator: x !is A"];
168 [label="Function call: (R|<local>/x| !is R|A|).R|kotlin/Boolean.not|()"];
169 [label="Exit when branch condition"];
}
170 [label="Synthetic else branch"];
171 [label="Enter when branch result"];
subgraph cluster_41 {
color=blue
172 [label="Enter block"];
173 [label="Access variable R|<local>/x|"];
174 [label="Function call: R|<local>/x|.R|/A.foo|()"];
175 [label="Exit block"];
}
176 [label="Exit when branch result"];
177 [label="Exit when"];
}
178 [label="Exit function test_8" style="filled" fillcolor=red];
}
163 -> {164};
164 -> {165};
165 -> {166};
166 -> {167};
167 -> {168};
168 -> {169};
169 -> {171 170};
170 -> {177};
171 -> {172};
172 -> {173};
173 -> {174};
174 -> {175};
175 -> {176};
176 -> {177};
177 -> {178};
}
@@ -56,12 +56,11 @@ digraph endlessLoops_kt {
} }
24 [label="Exit loop block"]; 24 [label="Exit loop block"];
} }
25 [label="Stub" style="filled" fillcolor=gray]; 25 [label="Exit whileloop"];
26 [label="Exit whileloop"];
} }
27 [label="Access variable R|<local>/x|"]; 26 [label="Access variable R|<local>/x|"];
28 [label="Function call: R|<local>/x|.R|/A.foo|()"]; 27 [label="Function call: R|<local>/x|.R|/A.foo|()"];
29 [label="Exit function test_1" style="filled" fillcolor=red]; 28 [label="Exit function test_1" style="filled" fillcolor=red];
} }
2 -> {3}; 2 -> {3};
@@ -81,7 +80,7 @@ digraph endlessLoops_kt {
15 -> {22}; 15 -> {22};
16 -> {17}; 16 -> {17};
17 -> {18}; 17 -> {18};
18 -> {26}; 18 -> {25};
18 -> {19} [style=dotted]; 18 -> {19} [style=dotted];
19 -> {20} [style=dotted]; 19 -> {20} [style=dotted];
20 -> {21} [style=dotted]; 20 -> {21} [style=dotted];
@@ -89,512 +88,499 @@ digraph endlessLoops_kt {
22 -> {23}; 22 -> {23};
23 -> {24}; 23 -> {24};
24 -> {4}; 24 -> {4};
25 -> {26} [style=dotted]; 25 -> {26};
26 -> {27}; 26 -> {27};
27 -> {28}; 27 -> {28};
28 -> {29};
subgraph cluster_9 { subgraph cluster_9 {
color=red color=red
30 [label="Enter function test_2" style="filled" fillcolor=red]; 29 [label="Enter function test_2" style="filled" fillcolor=red];
subgraph cluster_10 { subgraph cluster_10 {
color=blue color=blue
31 [label="Enter while loop"]; 30 [label="Enter while loop"];
subgraph cluster_11 { subgraph cluster_11 {
color=blue color=blue
32 [label="Enter loop condition"]; 31 [label="Enter loop condition"];
33 [label="Const: Boolean(true)"]; 32 [label="Const: Boolean(true)"];
34 [label="Exit loop condition"]; 33 [label="Exit loop condition"];
} }
subgraph cluster_12 { subgraph cluster_12 {
color=blue color=blue
35 [label="Enter loop block"]; 34 [label="Enter loop block"];
subgraph cluster_13 { subgraph cluster_13 {
color=blue color=blue
36 [label="Enter block"]; 35 [label="Enter block"];
subgraph cluster_14 { subgraph cluster_14 {
color=blue color=blue
37 [label="Enter when"]; 36 [label="Enter when"];
subgraph cluster_15 { subgraph cluster_15 {
color=blue color=blue
38 [label="Enter when branch condition "]; 37 [label="Enter when branch condition "];
39 [label="Access variable R|<local>/b|"]; 38 [label="Access variable R|<local>/b|"];
40 [label="Exit when branch condition"]; 39 [label="Exit when branch condition"];
} }
41 [label="Synthetic else branch"]; 40 [label="Synthetic else branch"];
42 [label="Enter when branch result"]; 41 [label="Enter when branch result"];
subgraph cluster_16 { subgraph cluster_16 {
color=blue color=blue
43 [label="Enter block"]; 42 [label="Enter block"];
44 [label="Access variable R|<local>/x|"]; 43 [label="Access variable R|<local>/x|"];
45 [label="Type operator: x as A"]; 44 [label="Type operator: x as A"];
46 [label="Jump: break@@@[Boolean(true)] "]; 45 [label="Jump: break@@@[Boolean(true)] "];
47 [label="Stub" style="filled" fillcolor=gray]; 46 [label="Stub" style="filled" fillcolor=gray];
48 [label="Exit block" style="filled" fillcolor=gray]; 47 [label="Exit block" style="filled" fillcolor=gray];
} }
49 [label="Exit when branch result" style="filled" fillcolor=gray]; 48 [label="Exit when branch result" style="filled" fillcolor=gray];
50 [label="Exit when"]; 49 [label="Exit when"];
} }
51 [label="Exit block"]; 50 [label="Exit block"];
} }
52 [label="Exit loop block"]; 51 [label="Exit loop block"];
} }
53 [label="Stub" style="filled" fillcolor=gray]; 52 [label="Exit whileloop"];
54 [label="Exit whileloop"];
} }
55 [label="Access variable R|<local>/x|"]; 53 [label="Access variable R|<local>/x|"];
56 [label="Function call: R|<local>/x|.R|/A.foo|()"]; 54 [label="Function call: R|<local>/x|.R|/A.foo|()"];
57 [label="Exit function test_2" style="filled" fillcolor=red]; 55 [label="Exit function test_2" style="filled" fillcolor=red];
} }
29 -> {30};
30 -> {31}; 30 -> {31};
31 -> {32}; 31 -> {32};
32 -> {33}; 32 -> {33};
33 -> {34}; 33 -> {34};
33 -> {52} [style=dotted];
34 -> {35}; 34 -> {35};
34 -> {53} [style=dotted];
35 -> {36}; 35 -> {36};
36 -> {37}; 36 -> {37};
37 -> {38}; 37 -> {38};
38 -> {39}; 38 -> {39};
39 -> {40}; 39 -> {41 40};
40 -> {42 41}; 40 -> {49};
41 -> {50}; 41 -> {42};
42 -> {43}; 42 -> {43};
43 -> {44}; 43 -> {44};
44 -> {45}; 44 -> {45};
45 -> {46}; 45 -> {52};
46 -> {54}; 45 -> {46} [style=dotted];
46 -> {47} [style=dotted]; 46 -> {47} [style=dotted];
47 -> {48} [style=dotted]; 47 -> {48} [style=dotted];
48 -> {49} [style=dotted]; 48 -> {49} [style=dotted];
49 -> {50} [style=dotted]; 49 -> {50};
50 -> {51}; 50 -> {51};
51 -> {52}; 51 -> {31};
52 -> {32}; 52 -> {53};
53 -> {54} [style=dotted]; 53 -> {54};
54 -> {55}; 54 -> {55};
55 -> {56};
56 -> {57};
subgraph cluster_17 { subgraph cluster_17 {
color=red color=red
58 [label="Enter function test_3" style="filled" fillcolor=red]; 56 [label="Enter function test_3" style="filled" fillcolor=red];
subgraph cluster_18 { subgraph cluster_18 {
color=blue color=blue
59 [label="Enter while loop"]; 57 [label="Enter while loop"];
subgraph cluster_19 { subgraph cluster_19 {
color=blue color=blue
60 [label="Enter loop condition"]; 58 [label="Enter loop condition"];
61 [label="Const: Boolean(true)"]; 59 [label="Const: Boolean(true)"];
62 [label="Exit loop condition"]; 60 [label="Exit loop condition"];
} }
subgraph cluster_20 { subgraph cluster_20 {
color=blue color=blue
63 [label="Enter loop block"]; 61 [label="Enter loop block"];
subgraph cluster_21 { subgraph cluster_21 {
color=blue color=blue
64 [label="Enter block"]; 62 [label="Enter block"];
65 [label="Access variable R|<local>/x|"]; 63 [label="Access variable R|<local>/x|"];
66 [label="Type operator: x as A"]; 64 [label="Type operator: x as A"];
subgraph cluster_22 { subgraph cluster_22 {
color=blue color=blue
67 [label="Enter when"]; 65 [label="Enter when"];
subgraph cluster_23 { subgraph cluster_23 {
color=blue color=blue
68 [label="Enter when branch condition "]; 66 [label="Enter when branch condition "];
69 [label="Access variable R|<local>/b|"]; 67 [label="Access variable R|<local>/b|"];
70 [label="Exit when branch condition"]; 68 [label="Exit when branch condition"];
} }
71 [label="Synthetic else branch"]; 69 [label="Synthetic else branch"];
72 [label="Enter when branch result"]; 70 [label="Enter when branch result"];
subgraph cluster_24 { subgraph cluster_24 {
color=blue color=blue
73 [label="Enter block"]; 71 [label="Enter block"];
74 [label="Jump: break@@@[Boolean(true)] "]; 72 [label="Jump: break@@@[Boolean(true)] "];
75 [label="Stub" style="filled" fillcolor=gray]; 73 [label="Stub" style="filled" fillcolor=gray];
76 [label="Exit block" style="filled" fillcolor=gray]; 74 [label="Exit block" style="filled" fillcolor=gray];
} }
77 [label="Exit when branch result" style="filled" fillcolor=gray]; 75 [label="Exit when branch result" style="filled" fillcolor=gray];
78 [label="Exit when"]; 76 [label="Exit when"];
} }
subgraph cluster_25 { subgraph cluster_25 {
color=blue color=blue
79 [label="Enter when"]; 77 [label="Enter when"];
subgraph cluster_26 { subgraph cluster_26 {
color=blue color=blue
80 [label="Enter when branch condition "]; 78 [label="Enter when branch condition "];
81 [label="Access variable R|<local>/b|"]; 79 [label="Access variable R|<local>/b|"];
82 [label="Exit when branch condition"]; 80 [label="Exit when branch condition"];
} }
83 [label="Synthetic else branch"]; 81 [label="Synthetic else branch"];
84 [label="Enter when branch result"]; 82 [label="Enter when branch result"];
subgraph cluster_27 { subgraph cluster_27 {
color=blue color=blue
85 [label="Enter block"]; 83 [label="Enter block"];
86 [label="Jump: break@@@[Boolean(true)] "]; 84 [label="Jump: break@@@[Boolean(true)] "];
87 [label="Stub" style="filled" fillcolor=gray]; 85 [label="Stub" style="filled" fillcolor=gray];
88 [label="Exit block" style="filled" fillcolor=gray]; 86 [label="Exit block" style="filled" fillcolor=gray];
} }
89 [label="Exit when branch result" style="filled" fillcolor=gray]; 87 [label="Exit when branch result" style="filled" fillcolor=gray];
90 [label="Exit when"]; 88 [label="Exit when"];
} }
91 [label="Exit block"]; 89 [label="Exit block"];
} }
92 [label="Exit loop block"]; 90 [label="Exit loop block"];
} }
93 [label="Stub" style="filled" fillcolor=gray]; 91 [label="Exit whileloop"];
94 [label="Exit whileloop"];
} }
95 [label="Access variable R|<local>/x|"]; 92 [label="Access variable R|<local>/x|"];
96 [label="Function call: R|<local>/x|.R|/A.foo|()"]; 93 [label="Function call: R|<local>/x|.R|/A.foo|()"];
97 [label="Exit function test_3" style="filled" fillcolor=red]; 94 [label="Exit function test_3" style="filled" fillcolor=red];
} }
56 -> {57};
57 -> {58};
58 -> {59}; 58 -> {59};
59 -> {60}; 59 -> {60};
60 -> {61}; 60 -> {61};
60 -> {91} [style=dotted];
61 -> {62}; 61 -> {62};
62 -> {63}; 62 -> {63};
62 -> {93} [style=dotted];
63 -> {64}; 63 -> {64};
64 -> {65}; 64 -> {65};
65 -> {66}; 65 -> {66};
66 -> {67}; 66 -> {67};
67 -> {68}; 67 -> {68};
68 -> {69}; 68 -> {70 69};
69 -> {70}; 69 -> {76};
70 -> {72 71}; 70 -> {71};
71 -> {78}; 71 -> {72};
72 -> {73}; 72 -> {91};
73 -> {74}; 72 -> {73} [style=dotted];
74 -> {94}; 73 -> {74} [style=dotted];
74 -> {75} [style=dotted]; 74 -> {75} [style=dotted];
75 -> {76} [style=dotted]; 75 -> {76} [style=dotted];
76 -> {77} [style=dotted]; 76 -> {77};
77 -> {78} [style=dotted]; 77 -> {78};
78 -> {79}; 78 -> {79};
79 -> {80}; 79 -> {80};
80 -> {81}; 80 -> {82 81};
81 -> {82}; 81 -> {88};
82 -> {84 83}; 82 -> {83};
83 -> {90}; 83 -> {84};
84 -> {85}; 84 -> {91};
85 -> {86}; 84 -> {85} [style=dotted];
86 -> {94}; 85 -> {86} [style=dotted];
86 -> {87} [style=dotted]; 86 -> {87} [style=dotted];
87 -> {88} [style=dotted]; 87 -> {88} [style=dotted];
88 -> {89} [style=dotted]; 88 -> {89};
89 -> {90} [style=dotted]; 89 -> {90};
90 -> {91}; 90 -> {58};
91 -> {92}; 91 -> {92};
92 -> {60}; 92 -> {93};
93 -> {94} [style=dotted]; 93 -> {94};
94 -> {95};
95 -> {96};
96 -> {97};
subgraph cluster_28 { subgraph cluster_28 {
color=red color=red
98 [label="Enter function test_4" style="filled" fillcolor=red]; 95 [label="Enter function test_4" style="filled" fillcolor=red];
subgraph cluster_29 { subgraph cluster_29 {
color=blue color=blue
99 [label="Enter while loop"]; 96 [label="Enter while loop"];
subgraph cluster_30 { subgraph cluster_30 {
color=blue color=blue
100 [label="Enter loop condition"]; 97 [label="Enter loop condition"];
101 [label="Const: Boolean(true)"]; 98 [label="Const: Boolean(true)"];
102 [label="Exit loop condition"]; 99 [label="Exit loop condition"];
} }
subgraph cluster_31 { subgraph cluster_31 {
color=blue color=blue
103 [label="Enter loop block"]; 100 [label="Enter loop block"];
subgraph cluster_32 { subgraph cluster_32 {
color=blue color=blue
104 [label="Enter block"]; 101 [label="Enter block"];
subgraph cluster_33 { subgraph cluster_33 {
color=blue color=blue
105 [label="Enter when"]; 102 [label="Enter when"];
subgraph cluster_34 { subgraph cluster_34 {
color=blue color=blue
106 [label="Enter when branch condition "]; 103 [label="Enter when branch condition "];
107 [label="Access variable R|<local>/b|"]; 104 [label="Access variable R|<local>/b|"];
108 [label="Exit when branch condition"]; 105 [label="Exit when branch condition"];
} }
109 [label="Synthetic else branch"]; 106 [label="Synthetic else branch"];
110 [label="Enter when branch result"]; 107 [label="Enter when branch result"];
subgraph cluster_35 { subgraph cluster_35 {
color=blue color=blue
111 [label="Enter block"]; 108 [label="Enter block"];
112 [label="Access variable R|<local>/x|"]; 109 [label="Access variable R|<local>/x|"];
113 [label="Type operator: x as A"]; 110 [label="Type operator: x as A"];
114 [label="Jump: break@@@[Boolean(true)] "]; 111 [label="Jump: break@@@[Boolean(true)] "];
115 [label="Stub" style="filled" fillcolor=gray]; 112 [label="Stub" style="filled" fillcolor=gray];
116 [label="Exit block" style="filled" fillcolor=gray]; 113 [label="Exit block" style="filled" fillcolor=gray];
} }
117 [label="Exit when branch result" style="filled" fillcolor=gray]; 114 [label="Exit when branch result" style="filled" fillcolor=gray];
118 [label="Exit when"]; 115 [label="Exit when"];
} }
119 [label="Jump: break@@@[Boolean(true)] "]; 116 [label="Jump: break@@@[Boolean(true)] "];
120 [label="Stub" style="filled" fillcolor=gray]; 117 [label="Stub" style="filled" fillcolor=gray];
121 [label="Exit block" style="filled" fillcolor=gray]; 118 [label="Exit block" style="filled" fillcolor=gray];
} }
122 [label="Exit loop block" style="filled" fillcolor=gray]; 119 [label="Exit loop block" style="filled" fillcolor=gray];
} }
123 [label="Stub" style="filled" fillcolor=gray]; 120 [label="Exit whileloop"];
124 [label="Exit whileloop"];
} }
125 [label="Access variable R|<local>/x|"]; 121 [label="Access variable R|<local>/x|"];
126 [label="Function call: R|<local>/x|.<Unresolved name: foo>#()"]; 122 [label="Function call: R|<local>/x|.<Unresolved name: foo>#()"];
127 [label="Exit function test_4" style="filled" fillcolor=red]; 123 [label="Exit function test_4" style="filled" fillcolor=red];
} }
95 -> {96};
96 -> {97};
97 -> {98};
98 -> {99}; 98 -> {99};
99 -> {100}; 99 -> {100};
99 -> {120} [style=dotted];
100 -> {101}; 100 -> {101};
101 -> {102}; 101 -> {102};
102 -> {103}; 102 -> {103};
102 -> {123} [style=dotted];
103 -> {104}; 103 -> {104};
104 -> {105}; 104 -> {105};
105 -> {106}; 105 -> {107 106};
106 -> {107}; 106 -> {115};
107 -> {108}; 107 -> {108};
108 -> {110 109}; 108 -> {109};
109 -> {118}; 109 -> {110};
110 -> {111}; 110 -> {111};
111 -> {112}; 111 -> {120};
112 -> {113}; 111 -> {112} [style=dotted];
113 -> {114}; 112 -> {113} [style=dotted];
114 -> {124}; 113 -> {114} [style=dotted];
114 -> {115} [style=dotted]; 114 -> {115} [style=dotted];
115 -> {116} [style=dotted]; 115 -> {116};
116 -> {120};
116 -> {117} [style=dotted]; 116 -> {117} [style=dotted];
117 -> {118} [style=dotted]; 117 -> {118} [style=dotted];
118 -> {119}; 118 -> {119} [style=dotted];
119 -> {124}; 119 -> {97} [style=dotted];
119 -> {120} [style=dotted]; 120 -> {121};
120 -> {121} [style=dotted]; 121 -> {122};
121 -> {122} [style=dotted]; 122 -> {123};
122 -> {100} [style=dotted];
123 -> {124} [style=dotted];
124 -> {125};
125 -> {126};
126 -> {127};
subgraph cluster_36 { subgraph cluster_36 {
color=red color=red
128 [label="Enter function test_5" style="filled" fillcolor=red]; 124 [label="Enter function test_5" style="filled" fillcolor=red];
subgraph cluster_37 { subgraph cluster_37 {
color=blue color=blue
129 [label="Enter do-while loop"]; 125 [label="Enter do-while loop"];
subgraph cluster_38 { subgraph cluster_38 {
color=blue color=blue
130 [label="Enter loop block"]; 126 [label="Enter loop block"];
subgraph cluster_39 { subgraph cluster_39 {
color=blue color=blue
131 [label="Enter block"]; 127 [label="Enter block"];
subgraph cluster_40 { subgraph cluster_40 {
color=blue color=blue
132 [label="Enter when"]; 128 [label="Enter when"];
subgraph cluster_41 { subgraph cluster_41 {
color=blue color=blue
133 [label="Enter when branch condition "]; 129 [label="Enter when branch condition "];
134 [label="Access variable R|<local>/b|"]; 130 [label="Access variable R|<local>/b|"];
135 [label="Exit when branch condition"]; 131 [label="Exit when branch condition"];
} }
136 [label="Synthetic else branch"]; 132 [label="Synthetic else branch"];
137 [label="Enter when branch result"]; 133 [label="Enter when branch result"];
subgraph cluster_42 { subgraph cluster_42 {
color=blue color=blue
138 [label="Enter block"]; 134 [label="Enter block"];
139 [label="Access variable R|<local>/x|"]; 135 [label="Access variable R|<local>/x|"];
140 [label="Type operator: x as A"]; 136 [label="Type operator: x as A"];
141 [label="Jump: break@@@[Boolean(true)] "]; 137 [label="Jump: break@@@[Boolean(true)] "];
142 [label="Stub" style="filled" fillcolor=gray]; 138 [label="Stub" style="filled" fillcolor=gray];
143 [label="Exit block" style="filled" fillcolor=gray]; 139 [label="Exit block" style="filled" fillcolor=gray];
} }
144 [label="Exit when branch result" style="filled" fillcolor=gray]; 140 [label="Exit when branch result" style="filled" fillcolor=gray];
145 [label="Exit when"]; 141 [label="Exit when"];
} }
146 [label="Exit block"]; 142 [label="Exit block"];
} }
147 [label="Exit loop block"]; 143 [label="Exit loop block"];
} }
subgraph cluster_43 { subgraph cluster_43 {
color=blue color=blue
148 [label="Enter loop condition"]; 144 [label="Enter loop condition"];
149 [label="Const: Boolean(true)"]; 145 [label="Const: Boolean(true)"];
150 [label="Exit loop condition"]; 146 [label="Exit loop condition"];
} }
151 [label="Stub" style="filled" fillcolor=gray]; 147 [label="Exit do-whileloop"];
152 [label="Exit do-whileloop"];
} }
153 [label="Access variable R|<local>/x|"]; 148 [label="Access variable R|<local>/x|"];
154 [label="Function call: R|<local>/x|.R|/A.foo|()"]; 149 [label="Function call: R|<local>/x|.R|/A.foo|()"];
155 [label="Exit function test_5" style="filled" fillcolor=red]; 150 [label="Exit function test_5" style="filled" fillcolor=red];
} }
124 -> {125};
125 -> {126};
126 -> {127};
127 -> {128};
128 -> {129}; 128 -> {129};
129 -> {130}; 129 -> {130};
130 -> {131}; 130 -> {131};
131 -> {132}; 131 -> {133 132};
132 -> {133}; 132 -> {141};
133 -> {134}; 133 -> {134};
134 -> {135}; 134 -> {135};
135 -> {137 136}; 135 -> {136};
136 -> {145}; 136 -> {137};
137 -> {138}; 137 -> {147};
138 -> {139}; 137 -> {138} [style=dotted];
139 -> {140}; 138 -> {139} [style=dotted];
140 -> {141}; 139 -> {140} [style=dotted];
141 -> {152}; 140 -> {141} [style=dotted];
141 -> {142} [style=dotted]; 141 -> {142};
142 -> {143} [style=dotted]; 142 -> {143};
143 -> {144} [style=dotted]; 143 -> {144};
144 -> {145} [style=dotted]; 144 -> {145};
145 -> {146}; 145 -> {146};
146 -> {147}; 146 -> {126};
146 -> {147} [style=dotted];
147 -> {148}; 147 -> {148};
148 -> {149}; 148 -> {149};
149 -> {150}; 149 -> {150};
150 -> {130};
150 -> {151} [style=dotted];
151 -> {152} [style=dotted];
152 -> {153};
153 -> {154};
154 -> {155};
subgraph cluster_44 { subgraph cluster_44 {
color=red color=red
156 [label="Enter function test_6" style="filled" fillcolor=red]; 151 [label="Enter function test_6" style="filled" fillcolor=red];
subgraph cluster_45 { subgraph cluster_45 {
color=blue color=blue
157 [label="Enter do-while loop"]; 152 [label="Enter do-while loop"];
subgraph cluster_46 { subgraph cluster_46 {
color=blue color=blue
158 [label="Enter loop block"]; 153 [label="Enter loop block"];
subgraph cluster_47 { subgraph cluster_47 {
color=blue color=blue
159 [label="Enter block"]; 154 [label="Enter block"];
160 [label="Access variable R|<local>/x|"]; 155 [label="Access variable R|<local>/x|"];
161 [label="Type operator: x as A"]; 156 [label="Type operator: x as A"];
subgraph cluster_48 { subgraph cluster_48 {
color=blue color=blue
162 [label="Enter when"]; 157 [label="Enter when"];
subgraph cluster_49 { subgraph cluster_49 {
color=blue color=blue
163 [label="Enter when branch condition "]; 158 [label="Enter when branch condition "];
164 [label="Access variable R|<local>/b|"]; 159 [label="Access variable R|<local>/b|"];
165 [label="Exit when branch condition"]; 160 [label="Exit when branch condition"];
} }
166 [label="Synthetic else branch"]; 161 [label="Synthetic else branch"];
167 [label="Enter when branch result"]; 162 [label="Enter when branch result"];
subgraph cluster_50 { subgraph cluster_50 {
color=blue color=blue
168 [label="Enter block"]; 163 [label="Enter block"];
169 [label="Jump: break@@@[Boolean(true)] "]; 164 [label="Jump: break@@@[Boolean(true)] "];
170 [label="Stub" style="filled" fillcolor=gray]; 165 [label="Stub" style="filled" fillcolor=gray];
171 [label="Exit block" style="filled" fillcolor=gray]; 166 [label="Exit block" style="filled" fillcolor=gray];
} }
172 [label="Exit when branch result" style="filled" fillcolor=gray]; 167 [label="Exit when branch result" style="filled" fillcolor=gray];
173 [label="Exit when"]; 168 [label="Exit when"];
} }
174 [label="Exit block"]; 169 [label="Exit block"];
} }
175 [label="Exit loop block"]; 170 [label="Exit loop block"];
} }
subgraph cluster_51 { subgraph cluster_51 {
color=blue color=blue
176 [label="Enter loop condition"]; 171 [label="Enter loop condition"];
177 [label="Const: Boolean(true)"]; 172 [label="Const: Boolean(true)"];
178 [label="Exit loop condition"]; 173 [label="Exit loop condition"];
} }
179 [label="Stub" style="filled" fillcolor=gray]; 174 [label="Exit do-whileloop"];
180 [label="Exit do-whileloop"];
} }
181 [label="Access variable R|<local>/x|"]; 175 [label="Access variable R|<local>/x|"];
182 [label="Function call: R|<local>/x|.R|/A.foo|()"]; 176 [label="Function call: R|<local>/x|.R|/A.foo|()"];
183 [label="Exit function test_6" style="filled" fillcolor=red]; 177 [label="Exit function test_6" style="filled" fillcolor=red];
} }
151 -> {152};
152 -> {153};
153 -> {154};
154 -> {155};
155 -> {156};
156 -> {157}; 156 -> {157};
157 -> {158}; 157 -> {158};
158 -> {159}; 158 -> {159};
159 -> {160}; 159 -> {160};
160 -> {161}; 160 -> {162 161};
161 -> {162}; 161 -> {168};
162 -> {163}; 162 -> {163};
163 -> {164}; 163 -> {164};
164 -> {165}; 164 -> {174};
165 -> {167 166}; 164 -> {165} [style=dotted];
166 -> {173}; 165 -> {166} [style=dotted];
167 -> {168}; 166 -> {167} [style=dotted];
167 -> {168} [style=dotted];
168 -> {169}; 168 -> {169};
169 -> {180}; 169 -> {170};
169 -> {170} [style=dotted]; 170 -> {171};
170 -> {171} [style=dotted]; 171 -> {172};
171 -> {172} [style=dotted]; 172 -> {173};
172 -> {173} [style=dotted]; 173 -> {153};
173 -> {174}; 173 -> {174} [style=dotted];
174 -> {175}; 174 -> {175};
175 -> {176}; 175 -> {176};
176 -> {177}; 176 -> {177};
177 -> {178};
178 -> {158};
178 -> {179} [style=dotted];
179 -> {180} [style=dotted];
180 -> {181};
181 -> {182};
182 -> {183};
subgraph cluster_52 { subgraph cluster_52 {
color=red color=red
184 [label="Enter function test_7" style="filled" fillcolor=red]; 178 [label="Enter function test_7" style="filled" fillcolor=red];
subgraph cluster_53 { subgraph cluster_53 {
color=blue color=blue
185 [label="Enter do-while loop"]; 179 [label="Enter do-while loop"];
subgraph cluster_54 { subgraph cluster_54 {
color=blue color=blue
186 [label="Enter loop block"]; 180 [label="Enter loop block"];
subgraph cluster_55 { subgraph cluster_55 {
color=blue color=blue
187 [label="Enter block"]; 181 [label="Enter block"];
188 [label="Access variable R|<local>/x|"]; 182 [label="Access variable R|<local>/x|"];
189 [label="Type operator: x as A"]; 183 [label="Type operator: x as A"];
190 [label="Exit block"]; 184 [label="Exit block"];
} }
191 [label="Exit loop block"]; 185 [label="Exit loop block"];
} }
subgraph cluster_56 { subgraph cluster_56 {
color=blue color=blue
192 [label="Enter loop condition"]; 186 [label="Enter loop condition"];
193 [label="Const: Boolean(true)"]; 187 [label="Const: Boolean(true)"];
194 [label="Exit loop condition"]; 188 [label="Exit loop condition"];
} }
195 [label="Stub" style="filled" fillcolor=gray]; 189 [label="Exit do-whileloop" style="filled" fillcolor=gray];
196 [label="Exit do-whileloop" style="filled" fillcolor=gray];
} }
197 [label="Access variable R|<local>/x|" style="filled" fillcolor=gray]; 190 [label="Access variable R|<local>/x|" style="filled" fillcolor=gray];
198 [label="Function call: R|<local>/x|.R|/A.foo|()" style="filled" fillcolor=gray]; 191 [label="Function call: R|<local>/x|.R|/A.foo|()" style="filled" fillcolor=gray];
199 [label="Exit function test_7" style="filled" fillcolor=red style="filled" fillcolor=gray]; 192 [label="Exit function test_7" style="filled" fillcolor=red style="filled" fillcolor=gray];
} }
178 -> {179};
179 -> {180};
180 -> {181};
181 -> {182};
182 -> {183};
183 -> {184};
184 -> {185}; 184 -> {185};
185 -> {186}; 185 -> {186};
186 -> {187}; 186 -> {187};
187 -> {188}; 187 -> {188};
188 -> {189}; 188 -> {180};
189 -> {190}; 188 -> {189} [style=dotted];
190 -> {191}; 189 -> {190} [style=dotted];
191 -> {192}; 190 -> {191} [style=dotted];
192 -> {193}; 191 -> {192} [style=dotted];
193 -> {194};
194 -> {186};
194 -> {195} [style=dotted];
195 -> {196} [style=dotted];
196 -> {197} [style=dotted];
197 -> {198} [style=dotted];
198 -> {199} [style=dotted];
} }
@@ -203,23 +203,22 @@ digraph safeCalls_kt {
^test_5 Unit ^test_5 Unit
} }
)" style="filled" fillcolor=gray]; )" style="filled" fillcolor=gray];
76 [label="Exit safe call" style="filled" fillcolor=gray]; 76 [label="Exit safe call"];
77 [label="Enter safe call" style="filled" fillcolor=gray]; 77 [label="Enter safe call"];
78 [label="Access variable R|<local>/x|" style="filled" fillcolor=gray]; 78 [label="Access variable R|<local>/x|"];
79 [label="Function call: R|<local>/x|.R|/A.bool|()" style="filled" fillcolor=gray]; 79 [label="Function call: R|<local>/x|.R|/A.bool|()"];
80 [label="Function call: R|<local>/x|?.R|kotlin/let|<R|A|, R|kotlin/Nothing|>(<L> = let@fun <anonymous>(it: R|A|): R|kotlin/Nothing| <kind=EXACTLY_ONCE> { 80 [label="Function call: R|<local>/x|?.R|kotlin/let|<R|A|, R|kotlin/Nothing|>(<L> = let@fun <anonymous>(it: R|A|): R|kotlin/Nothing| <kind=EXACTLY_ONCE> {
^test_5 Unit ^test_5 Unit
} }
)?.R|/boo|(R|<local>/x|.R|/A.bool|())" style="filled" fillcolor=gray]; )?.R|/boo|(R|<local>/x|.R|/A.bool|())"];
81 [label="Exit safe call" style="filled" fillcolor=gray]; 81 [label="Exit safe call"];
82 [label="Access variable R|<local>/x|" style="filled" fillcolor=gray]; 82 [label="Access variable R|<local>/x|"];
83 [label="Function call: R|<local>/x|.<Inapplicable(WRONG_RECEIVER): [/A.id]>#()" style="filled" fillcolor=gray]; 83 [label="Function call: R|<local>/x|.<Inapplicable(WRONG_RECEIVER): [/A.id]>#()"];
84 [label="Exit function test_5" style="filled" fillcolor=red]; 84 [label="Exit function test_5" style="filled" fillcolor=red];
} }
68 -> {69}; 68 -> {69};
69 -> {70}; 69 -> {70 76};
69 -> {76} [style=dotted];
70 -> {71}; 70 -> {71};
71 -> {72}; 71 -> {72};
72 -> {84}; 72 -> {84};
@@ -227,13 +226,13 @@ digraph safeCalls_kt {
73 -> {74} [style=dotted]; 73 -> {74} [style=dotted];
74 -> {75} [style=dotted]; 74 -> {75} [style=dotted];
75 -> {76} [style=dotted]; 75 -> {76} [style=dotted];
76 -> {77 81} [style=dotted]; 76 -> {77 81};
77 -> {78} [style=dotted]; 77 -> {78};
78 -> {79} [style=dotted]; 78 -> {79};
79 -> {80} [style=dotted]; 79 -> {80};
80 -> {81} [style=dotted]; 80 -> {81};
81 -> {82} [style=dotted]; 81 -> {82};
82 -> {83} [style=dotted]; 82 -> {83};
83 -> {84} [style=dotted]; 83 -> {84};
} }
@@ -5,18 +5,20 @@
package org.jetbrains.kotlin.fir package org.jetbrains.kotlin.fir
import junit.framework.TestCase
import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.references.FirControlFlowGraphReference import org.jetbrains.kotlin.fir.references.FirControlFlowGraphReference
import org.jetbrains.kotlin.fir.resolve.dfa.FirControlFlowGraphReferenceImpl import org.jetbrains.kotlin.fir.resolve.dfa.FirControlFlowGraphReferenceImpl
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.* import org.jetbrains.kotlin.fir.resolve.dfa.cfg.CFGNode
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.ControlFlowGraph
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.EdgeKind
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.FirControlFlowGraphRenderVisitor
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
import org.jetbrains.kotlin.test.ConfigurationKind import org.jetbrains.kotlin.test.ConfigurationKind
import org.jetbrains.kotlin.test.KotlinTestUtils import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase
import java.io.File import java.io.File
private const val EDGE = " -> "
private const val INDENT = " "
private const val RED = "red"
private const val BLUE = "blue"
/* /*
* For comfort viewing dumps of control flow graph you can setup external tool in IDEA that opens .dot files * For comfort viewing dumps of control flow graph you can setup external tool in IDEA that opens .dot files
@@ -43,122 +45,53 @@ abstract class AbstractFirDiagnosticsWithCfgTest : AbstractFirDiagnosticsTest()
super.runAnalysis(testDataFile, testFiles, firFilesPerSession) super.runAnalysis(testDataFile, testFiles, firFilesPerSession)
val allFirFiles = firFilesPerSession.values.flatten() val allFirFiles = firFilesPerSession.values.flatten()
checkCfg(testDataFile, allFirFiles) checkCfg(testDataFile, allFirFiles)
checkCfgEdgeConsistency(allFirFiles)
} }
fun checkCfg(testDataFile: File, firFiles: List<FirFile>) { private fun checkCfg(testDataFile: File, firFiles: List<FirFile>) {
val simpleBuilder = StringBuilder() val builder = StringBuilder()
val dotBuilder = StringBuilder()
firFiles.first().accept(FirControlFlowGraphRenderVisitor(simpleBuilder, dotBuilder), null) firFiles.first().accept(FirControlFlowGraphRenderVisitor(builder), null)
val dotCfgDump = dotBuilder.toString() val dotCfgDump = builder.toString()
val dotExpectedPath = testDataFile.absolutePath.replace(".kt", ".dot") val dotExpectedPath = testDataFile.absolutePath.replace(".kt", ".dot")
KotlinTestUtils.assertEqualsToFile(File(dotExpectedPath), dotCfgDump) KotlinTestUtils.assertEqualsToFile(File(dotExpectedPath), dotCfgDump)
} }
private class FirControlFlowGraphRenderVisitor( private fun checkCfgEdgeConsistency(firFiles: List<FirFile>) {
private val simpleBuilder: StringBuilder, firFiles.forEach { it.accept(CfgConsistencyChecker) }
private val dotBuilder: StringBuilder
) : FirVisitorVoid() {
private var indexOffset = 0
private var clusterCounter = 0
private var offset = 1
override fun visitFile(file: FirFile) {
dotBuilder.appendln("digraph ${file.name.replace(".", "_")} {")
.appendln("${INDENT}graph [splines=ortho nodesep=3]")
.appendln("${INDENT}node [shape=box penwidth=2]")
.appendln("${INDENT}edge [penwidth=2]")
.appendln()
visitElement(file)
dotBuilder.appendln("}")
} }
private object CfgConsistencyChecker : FirVisitorVoid() {
override fun visitElement(element: FirElement) { override fun visitElement(element: FirElement) {
element.acceptChildren(this) element.acceptChildren(this)
} }
override fun visitControlFlowGraphReference(controlFlowGraphReference: FirControlFlowGraphReference) { override fun visitControlFlowGraphReference(controlFlowGraphReference: FirControlFlowGraphReference) {
val controlFlowGraph = (controlFlowGraphReference as? FirControlFlowGraphReferenceImpl)?.controlFlowGraph ?: return val graph = (controlFlowGraphReference as? FirControlFlowGraphReferenceImpl)?.controlFlowGraph ?: return
controlFlowGraph.renderToStringBuilder(simpleBuilder) checkConsistency(graph)
indexOffset = controlFlowGraph.dotRenderToStringBuilder(dotBuilder)
dotBuilder.appendln()
} }
private fun StringBuilder.enterCluster(color: String) { private fun checkConsistency(graph: ControlFlowGraph) {
indent() for (node in graph.nodes) {
appendln("subgraph cluster_${clusterCounter++} {") for (to in node.followingNodes) {
offset++ checkEdge(node, to)
indent() }
appendln("color=$color") for (from in node.previousNodes) {
checkEdge(from, node)
}
TestCase.assertTrue(node.followingNodes.isNotEmpty() || node.previousNodes.isNotEmpty())
}
} }
private fun StringBuilder.exitCluster() { private fun checkEdge(from: CFGNode<*>, to: CFGNode<*>) {
offset-- KtUsefulTestCase.assertContainsElements(from.followingNodes, to)
indent() KtUsefulTestCase.assertContainsElements(to.previousNodes, from)
appendln("}") val fromKind = from.outgoingEdges.getValue(to)
} val toKind = to.incomingEdges.getValue(from)
TestCase.assertEquals(fromKind, toKind)
private fun StringBuilder.indent() { if (from.isDead || to.isDead) {
append(INDENT.repeat(offset)) TestCase.assertEquals(EdgeKind.Dead, fromKind)
}
fun ControlFlowGraph.dotRenderToStringBuilder(builder: StringBuilder): Int {
with(builder) {
val sortedNodes = sortNodes()
val indices = sortedNodes.indicesMap().mapValues { (_, index) -> index + indexOffset }
fun CFGNode<*>.splitEdges(): Pair<List<CFGNode<*>>, List<CFGNode<*>>> =
if (isDead) emptyList<CFGNode<*>>() to followingNodes
else followingNodes.filter { !it.isDead } to followingNodes.filter { it.isDead }
var color = RED
sortedNodes.forEach {
if (it is EnterNode) {
enterCluster(color)
color = BLUE
}
indent()
append(indices.getValue(it))
val attributes = mutableListOf<String>()
attributes += "label=\"${it.render().replace("\"", "")}\""
if (it == enterNode || it == exitNode) {
attributes += "style=\"filled\""
attributes += "fillcolor=red"
}
if (it.isDead) {
attributes += "style=\"filled\""
attributes += "fillcolor=gray"
}
appendln(attributes.joinToString(separator = " ", prefix = " [", postfix = "];"))
if (it is ExitNode) {
exitCluster()
}
}
appendln()
sortedNodes.forEachIndexed { i, node ->
if (node.followingNodes.isEmpty()) return@forEachIndexed
val (aliveEdges, deadEdges) = node.splitEdges()
fun renderEdges(edges: List<CFGNode<*>>, isDead: Boolean) {
if (edges.isEmpty()) return
indent()
append(i + indexOffset)
append(EDGE)
append(edges.joinToString(prefix = "{", postfix = "}", separator = " ") { indices.getValue(it).toString() })
if (isDead) {
append(" [style=dotted]")
}
appendln(";")
}
renderEdges(aliveEdges, false)
renderEdges(deadEdges, true)
}
return indexOffset + sortedNodes.size
} }
} }
} }