FIR CFA: remove modes
They are only used in one place that can just as well use kinds. Especially considering that "the one place" used them incorrectly and would not attach local functions in property accessors as subgraphs.
This commit is contained in:
+146
-144
@@ -78,228 +78,229 @@ digraph propertiesAndInitBlocks_kt {
|
|||||||
|
|
||||||
subgraph cluster_8 {
|
subgraph cluster_8 {
|
||||||
color=red
|
color=red
|
||||||
46 [label="Enter function foo" style="filled" fillcolor=red];
|
58 [label="Enter function getter" style="filled" fillcolor=red];
|
||||||
subgraph cluster_9 {
|
subgraph cluster_9 {
|
||||||
color=blue
|
color=blue
|
||||||
47 [label="Enter block"];
|
59 [label="Enter block"];
|
||||||
48 [label="Const: Int(1)"];
|
60 [label="Exit local class <getter>"];
|
||||||
49 [label="Const: Int(1)"];
|
61 [label="Exit block"];
|
||||||
50 [label="Function call: Int(1).R|kotlin/Int.plus|(...)" style="filled" fillcolor=yellow];
|
|
||||||
51 [label="Variable declaration: lval c: R|kotlin/Int|"];
|
|
||||||
52 [label="Function call: R|java/lang/Exception.Exception|()" style="filled" fillcolor=yellow];
|
|
||||||
53 [label="Throw: throw R|java/lang/Exception.Exception|()"];
|
|
||||||
54 [label="Stub" style="filled" fillcolor=gray];
|
|
||||||
55 [label="Exit block" style="filled" fillcolor=gray];
|
|
||||||
}
|
}
|
||||||
56 [label="Exit function foo" style="filled" fillcolor=red style="filled" fillcolor=gray];
|
62 [label="Exit function getter" style="filled" fillcolor=red];
|
||||||
}
|
}
|
||||||
46 -> {47};
|
|
||||||
47 -> {48};
|
|
||||||
48 -> {49};
|
|
||||||
49 -> {50};
|
|
||||||
50 -> {51};
|
|
||||||
51 -> {52};
|
|
||||||
52 -> {53};
|
|
||||||
53 -> {54} [style=dotted];
|
|
||||||
54 -> {55} [style=dotted];
|
|
||||||
55 -> {56} [style=dotted];
|
|
||||||
|
|
||||||
subgraph cluster_10 {
|
subgraph cluster_10 {
|
||||||
color=red
|
color=blue
|
||||||
57 [label="Enter function getter" style="filled" fillcolor=red];
|
63 [label="Enter class GetterLocalClass" style="filled" fillcolor=red];
|
||||||
|
64 [label="Part of class initialization"];
|
||||||
subgraph cluster_11 {
|
subgraph cluster_11 {
|
||||||
color=blue
|
color=blue
|
||||||
58 [label="Enter block"];
|
66 [label="Enter init block" style="filled" fillcolor=red];
|
||||||
59 [label="Exit local class <getter>"];
|
subgraph cluster_12 {
|
||||||
60 [label="Exit block"];
|
|
||||||
}
|
|
||||||
61 [label="Exit function getter" style="filled" fillcolor=red];
|
|
||||||
}
|
|
||||||
subgraph cluster_12 {
|
|
||||||
color=blue
|
|
||||||
62 [label="Enter class GetterLocalClass" style="filled" fillcolor=red];
|
|
||||||
63 [label="Part of class initialization"];
|
|
||||||
subgraph cluster_13 {
|
|
||||||
color=blue
|
|
||||||
65 [label="Enter init block" style="filled" fillcolor=red];
|
|
||||||
subgraph cluster_14 {
|
|
||||||
color=blue
|
color=blue
|
||||||
66 [label="Enter block"];
|
67 [label="Enter block"];
|
||||||
67 [label="Function call: R|java/lang/Exception.Exception|()" style="filled" fillcolor=yellow];
|
68 [label="Function call: R|java/lang/Exception.Exception|()" style="filled" fillcolor=yellow];
|
||||||
68 [label="Throw: throw R|java/lang/Exception.Exception|()"];
|
69 [label="Throw: throw R|java/lang/Exception.Exception|()"];
|
||||||
69 [label="Stub" style="filled" fillcolor=gray];
|
70 [label="Stub" style="filled" fillcolor=gray];
|
||||||
70 [label="Exit block" style="filled" fillcolor=gray];
|
71 [label="Exit block" style="filled" fillcolor=gray];
|
||||||
}
|
}
|
||||||
71 [label="Exit init block" style="filled" fillcolor=red style="filled" fillcolor=gray];
|
72 [label="Exit init block" style="filled" fillcolor=red style="filled" fillcolor=gray];
|
||||||
}
|
}
|
||||||
64 [label="Exit class GetterLocalClass" style="filled" fillcolor=red style="filled" fillcolor=gray];
|
65 [label="Exit class GetterLocalClass" style="filled" fillcolor=red style="filled" fillcolor=gray];
|
||||||
}
|
}
|
||||||
subgraph cluster_15 {
|
subgraph cluster_13 {
|
||||||
color=blue
|
color=blue
|
||||||
72 [label="Enter function <init>" style="filled" fillcolor=red style="filled" fillcolor=gray];
|
73 [label="Enter function <init>" style="filled" fillcolor=red style="filled" fillcolor=gray];
|
||||||
73 [label="Delegated constructor call: super<R|kotlin/Any|>()" style="filled" fillcolor=yellow];
|
74 [label="Delegated constructor call: super<R|kotlin/Any|>()" style="filled" fillcolor=yellow];
|
||||||
74 [label="Exit function <init>" style="filled" fillcolor=red];
|
75 [label="Exit function <init>" style="filled" fillcolor=red];
|
||||||
}
|
}
|
||||||
57 -> {58};
|
|
||||||
58 -> {59};
|
58 -> {59};
|
||||||
58 -> {65 72} [color=red];
|
|
||||||
59 -> {60};
|
59 -> {60};
|
||||||
59 -> {62} [color=green];
|
59 -> {66 73} [color=red];
|
||||||
59 -> {62} [style=dashed];
|
|
||||||
60 -> {61};
|
60 -> {61};
|
||||||
62 -> {63} [color=green];
|
60 -> {63} [color=green];
|
||||||
63 -> {65} [color=green];
|
60 -> {63} [style=dashed];
|
||||||
63 -> {64} [style=dotted];
|
61 -> {62};
|
||||||
63 -> {65} [style=dashed];
|
63 -> {64} [color=green];
|
||||||
64 -> {72} [style=dotted];
|
64 -> {66} [color=green];
|
||||||
64 -> {72} [style=dashed];
|
64 -> {65} [style=dotted];
|
||||||
65 -> {66};
|
64 -> {66} [style=dashed];
|
||||||
|
65 -> {73} [style=dotted];
|
||||||
|
65 -> {73} [style=dashed];
|
||||||
66 -> {67};
|
66 -> {67};
|
||||||
67 -> {68};
|
67 -> {68};
|
||||||
68 -> {69} [style=dotted];
|
68 -> {69};
|
||||||
69 -> {70} [style=dotted];
|
69 -> {70} [style=dotted];
|
||||||
70 -> {71} [style=dotted];
|
70 -> {71} [style=dotted];
|
||||||
71 -> {64} [style=dotted];
|
71 -> {72} [style=dotted];
|
||||||
72 -> {73};
|
72 -> {65} [style=dotted];
|
||||||
73 -> {74};
|
73 -> {74};
|
||||||
|
74 -> {75};
|
||||||
|
|
||||||
subgraph cluster_16 {
|
subgraph cluster_14 {
|
||||||
color=red
|
color=red
|
||||||
75 [label="Enter property" style="filled" fillcolor=red];
|
76 [label="Enter property" style="filled" fillcolor=red];
|
||||||
76 [label="Postponed enter to lambda"];
|
77 [label="Postponed enter to lambda"];
|
||||||
subgraph cluster_17 {
|
subgraph cluster_15 {
|
||||||
color=blue
|
color=blue
|
||||||
24 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
|
24 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
|
||||||
subgraph cluster_18 {
|
subgraph cluster_16 {
|
||||||
color=blue
|
color=blue
|
||||||
25 [label="Enter block"];
|
25 [label="Enter block"];
|
||||||
26 [label="Exit local class <anonymous>"];
|
26 [label="Local function declaration <anonymous>"];
|
||||||
27 [label="Function call: R|java/lang/Exception.Exception|()" style="filled" fillcolor=yellow];
|
27 [label="Exit local class <anonymous>"];
|
||||||
28 [label="Throw: throw R|java/lang/Exception.Exception|()"];
|
28 [label="Function call: R|java/lang/Exception.Exception|()" style="filled" fillcolor=yellow];
|
||||||
29 [label="Stub" style="filled" fillcolor=gray];
|
29 [label="Throw: throw R|java/lang/Exception.Exception|()"];
|
||||||
30 [label="Exit block" style="filled" fillcolor=gray];
|
30 [label="Stub" style="filled" fillcolor=gray];
|
||||||
|
31 [label="Exit block" style="filled" fillcolor=gray];
|
||||||
}
|
}
|
||||||
31 [label="Exit function anonymousFunction" style="filled" fillcolor=red style="filled" fillcolor=gray];
|
32 [label="Exit function anonymousFunction" style="filled" fillcolor=red style="filled" fillcolor=gray];
|
||||||
}
|
}
|
||||||
subgraph cluster_19 {
|
subgraph cluster_17 {
|
||||||
color=blue
|
color=blue
|
||||||
32 [label="Enter class InitializerLocalClass" style="filled" fillcolor=red];
|
44 [label="Enter class InitializerLocalClass" style="filled" fillcolor=red];
|
||||||
33 [label="Part of class initialization"];
|
45 [label="Part of class initialization"];
|
||||||
subgraph cluster_20 {
|
subgraph cluster_18 {
|
||||||
color=blue
|
color=blue
|
||||||
35 [label="Enter init block" style="filled" fillcolor=red];
|
47 [label="Enter init block" style="filled" fillcolor=red];
|
||||||
subgraph cluster_21 {
|
subgraph cluster_19 {
|
||||||
color=blue
|
color=blue
|
||||||
36 [label="Enter block"];
|
48 [label="Enter block"];
|
||||||
37 [label="Function call: R|java/lang/Exception.Exception|()" style="filled" fillcolor=yellow];
|
49 [label="Function call: R|java/lang/Exception.Exception|()" style="filled" fillcolor=yellow];
|
||||||
38 [label="Throw: throw R|java/lang/Exception.Exception|()"];
|
50 [label="Throw: throw R|java/lang/Exception.Exception|()"];
|
||||||
39 [label="Stub" style="filled" fillcolor=gray];
|
51 [label="Stub" style="filled" fillcolor=gray];
|
||||||
40 [label="Const: Int(1)" style="filled" fillcolor=gray];
|
52 [label="Const: Int(1)" style="filled" fillcolor=gray];
|
||||||
41 [label="Exit block" style="filled" fillcolor=gray];
|
53 [label="Exit block" style="filled" fillcolor=gray];
|
||||||
}
|
}
|
||||||
42 [label="Exit init block" style="filled" fillcolor=red style="filled" fillcolor=gray];
|
54 [label="Exit init block" style="filled" fillcolor=red style="filled" fillcolor=gray];
|
||||||
}
|
}
|
||||||
34 [label="Exit class InitializerLocalClass" style="filled" fillcolor=red style="filled" fillcolor=gray];
|
46 [label="Exit class InitializerLocalClass" style="filled" fillcolor=red style="filled" fillcolor=gray];
|
||||||
}
|
}
|
||||||
subgraph cluster_22 {
|
subgraph cluster_20 {
|
||||||
color=blue
|
color=blue
|
||||||
43 [label="Enter function <init>" style="filled" fillcolor=red style="filled" fillcolor=gray];
|
55 [label="Enter function <init>" style="filled" fillcolor=red style="filled" fillcolor=gray];
|
||||||
44 [label="Delegated constructor call: super<R|kotlin/Any|>()" style="filled" fillcolor=yellow];
|
56 [label="Delegated constructor call: super<R|kotlin/Any|>()" style="filled" fillcolor=yellow];
|
||||||
45 [label="Exit function <init>" style="filled" fillcolor=red];
|
57 [label="Exit function <init>" style="filled" fillcolor=red];
|
||||||
}
|
}
|
||||||
77 [label="Postponed exit from lambda"];
|
subgraph cluster_21 {
|
||||||
78 [label="Function call: R|/run|(...)" style="filled" fillcolor=yellow];
|
color=blue
|
||||||
79 [label="Exit property" style="filled" fillcolor=red];
|
33 [label="Enter function foo" style="filled" fillcolor=red];
|
||||||
|
subgraph cluster_22 {
|
||||||
|
color=blue
|
||||||
|
34 [label="Enter block"];
|
||||||
|
35 [label="Const: Int(1)"];
|
||||||
|
36 [label="Const: Int(1)"];
|
||||||
|
37 [label="Function call: Int(1).R|kotlin/Int.plus|(...)" style="filled" fillcolor=yellow];
|
||||||
|
38 [label="Variable declaration: lval c: R|kotlin/Int|"];
|
||||||
|
39 [label="Function call: R|java/lang/Exception.Exception|()" style="filled" fillcolor=yellow];
|
||||||
|
40 [label="Throw: throw R|java/lang/Exception.Exception|()"];
|
||||||
|
41 [label="Stub" style="filled" fillcolor=gray];
|
||||||
|
42 [label="Exit block" style="filled" fillcolor=gray];
|
||||||
|
}
|
||||||
|
43 [label="Exit function foo" style="filled" fillcolor=red style="filled" fillcolor=gray];
|
||||||
|
}
|
||||||
|
78 [label="Postponed exit from lambda"];
|
||||||
|
79 [label="Function call: R|/run|(...)" style="filled" fillcolor=yellow];
|
||||||
|
80 [label="Exit property" style="filled" fillcolor=red];
|
||||||
}
|
}
|
||||||
75 -> {76};
|
76 -> {77};
|
||||||
76 -> {24 77 78};
|
77 -> {24 78 79};
|
||||||
76 -> {24} [style=dashed];
|
77 -> {24} [style=dashed];
|
||||||
77 -> {78};
|
|
||||||
77 -> {76} [color=green style=dashed];
|
|
||||||
78 -> {79};
|
78 -> {79};
|
||||||
|
78 -> {77} [color=green style=dashed];
|
||||||
|
79 -> {80};
|
||||||
24 -> {25};
|
24 -> {25};
|
||||||
25 -> {26};
|
25 -> {26};
|
||||||
25 -> {35 43 46} [color=red];
|
26 -> {27 33};
|
||||||
26 -> {27};
|
26 -> {47 55} [color=red];
|
||||||
26 -> {32} [color=green];
|
26 -> {33} [style=dashed];
|
||||||
26 -> {32} [style=dashed];
|
|
||||||
27 -> {28};
|
27 -> {28};
|
||||||
28 -> {29} [style=dotted];
|
27 -> {44} [color=green];
|
||||||
|
27 -> {44} [style=dashed];
|
||||||
|
28 -> {29};
|
||||||
29 -> {30} [style=dotted];
|
29 -> {30} [style=dotted];
|
||||||
30 -> {31} [style=dotted];
|
30 -> {31} [style=dotted];
|
||||||
31 -> {77} [style=dotted];
|
31 -> {32} [style=dotted];
|
||||||
32 -> {33} [color=green];
|
32 -> {78} [style=dotted];
|
||||||
33 -> {35} [color=green];
|
33 -> {34};
|
||||||
33 -> {34} [style=dotted];
|
34 -> {35};
|
||||||
33 -> {35} [style=dashed];
|
|
||||||
34 -> {43} [style=dotted];
|
|
||||||
34 -> {43} [style=dashed];
|
|
||||||
35 -> {36};
|
35 -> {36};
|
||||||
36 -> {37};
|
36 -> {37};
|
||||||
37 -> {38};
|
37 -> {38};
|
||||||
38 -> {39} [style=dotted];
|
38 -> {39};
|
||||||
39 -> {40} [style=dotted];
|
39 -> {40};
|
||||||
40 -> {41} [style=dotted];
|
40 -> {41} [style=dotted];
|
||||||
41 -> {42} [style=dotted];
|
41 -> {42} [style=dotted];
|
||||||
42 -> {34} [style=dotted];
|
42 -> {43} [style=dotted];
|
||||||
43 -> {44};
|
44 -> {45} [color=green];
|
||||||
44 -> {45};
|
45 -> {47} [color=green];
|
||||||
|
45 -> {46} [style=dotted];
|
||||||
|
45 -> {47} [style=dashed];
|
||||||
|
46 -> {55} [style=dotted];
|
||||||
|
46 -> {55} [style=dashed];
|
||||||
|
47 -> {48};
|
||||||
|
48 -> {49};
|
||||||
|
49 -> {50};
|
||||||
|
50 -> {51} [style=dotted];
|
||||||
|
51 -> {52} [style=dotted];
|
||||||
|
52 -> {53} [style=dotted];
|
||||||
|
53 -> {54} [style=dotted];
|
||||||
|
54 -> {46} [style=dotted];
|
||||||
|
55 -> {56};
|
||||||
|
56 -> {57};
|
||||||
|
|
||||||
subgraph cluster_23 {
|
subgraph cluster_23 {
|
||||||
color=red
|
color=red
|
||||||
80 [label="Enter property" style="filled" fillcolor=red];
|
81 [label="Enter property" style="filled" fillcolor=red];
|
||||||
subgraph cluster_24 {
|
subgraph cluster_24 {
|
||||||
color=blue
|
color=blue
|
||||||
81 [label="Try expression enter"];
|
82 [label="Try expression enter"];
|
||||||
subgraph cluster_25 {
|
subgraph cluster_25 {
|
||||||
color=blue
|
color=blue
|
||||||
82 [label="Try main block enter"];
|
83 [label="Try main block enter"];
|
||||||
subgraph cluster_26 {
|
subgraph cluster_26 {
|
||||||
color=blue
|
color=blue
|
||||||
83 [label="Enter block"];
|
84 [label="Enter block"];
|
||||||
84 [label="Const: Int(1)"];
|
85 [label="Const: Int(1)"];
|
||||||
85 [label="Exit block"];
|
86 [label="Exit block"];
|
||||||
}
|
}
|
||||||
86 [label="Try main block exit"];
|
87 [label="Try main block exit"];
|
||||||
}
|
}
|
||||||
subgraph cluster_27 {
|
subgraph cluster_27 {
|
||||||
color=blue
|
color=blue
|
||||||
87 [label="Catch enter"];
|
88 [label="Catch enter"];
|
||||||
88 [label="Variable declaration: e: R|kotlin/Exception|"];
|
89 [label="Variable declaration: e: R|kotlin/Exception|"];
|
||||||
subgraph cluster_28 {
|
subgraph cluster_28 {
|
||||||
color=blue
|
color=blue
|
||||||
89 [label="Enter block"];
|
90 [label="Enter block"];
|
||||||
90 [label="Const: Int(2)"];
|
91 [label="Const: Int(2)"];
|
||||||
91 [label="Exit block"];
|
92 [label="Exit block"];
|
||||||
}
|
}
|
||||||
92 [label="Catch exit"];
|
93 [label="Catch exit"];
|
||||||
}
|
}
|
||||||
subgraph cluster_29 {
|
subgraph cluster_29 {
|
||||||
color=blue
|
color=blue
|
||||||
93 [label="Enter finally"];
|
94 [label="Enter finally"];
|
||||||
subgraph cluster_30 {
|
subgraph cluster_30 {
|
||||||
color=blue
|
color=blue
|
||||||
94 [label="Enter block"];
|
95 [label="Enter block"];
|
||||||
95 [label="Const: Int(0)"];
|
96 [label="Const: Int(0)"];
|
||||||
96 [label="Exit block"];
|
97 [label="Exit block"];
|
||||||
}
|
}
|
||||||
97 [label="Exit finally"];
|
98 [label="Exit finally"];
|
||||||
}
|
}
|
||||||
98 [label="Try expression exit"];
|
99 [label="Try expression exit"];
|
||||||
}
|
}
|
||||||
99 [label="Exit property" style="filled" fillcolor=red];
|
100 [label="Exit property" style="filled" fillcolor=red];
|
||||||
}
|
}
|
||||||
80 -> {81};
|
81 -> {82};
|
||||||
81 -> {82 87};
|
82 -> {83 88};
|
||||||
81 -> {93} [label="onUncaughtException"];
|
82 -> {94} [label="onUncaughtException"];
|
||||||
82 -> {83};
|
|
||||||
83 -> {84};
|
83 -> {84};
|
||||||
84 -> {85};
|
84 -> {85};
|
||||||
85 -> {86};
|
85 -> {86};
|
||||||
86 -> {87 93};
|
86 -> {87};
|
||||||
87 -> {88};
|
87 -> {88 94};
|
||||||
87 -> {93} [label="onUncaughtException"];
|
|
||||||
88 -> {89};
|
88 -> {89};
|
||||||
|
88 -> {94} [label="onUncaughtException"];
|
||||||
89 -> {90};
|
89 -> {90};
|
||||||
90 -> {91};
|
90 -> {91};
|
||||||
91 -> {92};
|
91 -> {92};
|
||||||
@@ -310,5 +311,6 @@ digraph propertiesAndInitBlocks_kt {
|
|||||||
96 -> {97};
|
96 -> {97};
|
||||||
97 -> {98};
|
97 -> {98};
|
||||||
98 -> {99};
|
98 -> {99};
|
||||||
|
99 -> {100};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-55
@@ -23,15 +23,10 @@ import org.jetbrains.kotlin.fir.util.listMultimapOf
|
|||||||
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
|
|
||||||
@RequiresOptIn
|
|
||||||
private annotation class CfgBuilderInternals
|
|
||||||
|
|
||||||
@OptIn(CfgInternals::class)
|
@OptIn(CfgInternals::class)
|
||||||
class ControlFlowGraphBuilder {
|
class ControlFlowGraphBuilder {
|
||||||
@CfgBuilderInternals
|
|
||||||
private val graphs: Stack<ControlFlowGraph> = stackOf(ControlFlowGraph(null, "<TOP_LEVEL_GRAPH>", ControlFlowGraph.Kind.TopLevel))
|
private val graphs: Stack<ControlFlowGraph> = stackOf(ControlFlowGraph(null, "<TOP_LEVEL_GRAPH>", ControlFlowGraph.Kind.TopLevel))
|
||||||
|
|
||||||
@get:OptIn(CfgBuilderInternals::class)
|
|
||||||
val currentGraph: ControlFlowGraph
|
val currentGraph: ControlFlowGraph
|
||||||
get() = graphs.top()
|
get() = graphs.top()
|
||||||
|
|
||||||
@@ -44,13 +39,6 @@ class ControlFlowGraphBuilder {
|
|||||||
|
|
||||||
var levelCounter: Int = 0
|
var levelCounter: Int = 0
|
||||||
|
|
||||||
private val modes: Stack<Mode> = stackOf(Mode.TopLevel)
|
|
||||||
private val mode: Mode get() = modes.top()
|
|
||||||
|
|
||||||
private enum class Mode {
|
|
||||||
Function, TopLevel, Body, ClassInitializer, PropertyInitializer, FieldInitializer
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------- Node caches -----------------------------------
|
// ----------------------------------- Node caches -----------------------------------
|
||||||
|
|
||||||
private val exitTargetsForReturn: SymbolBasedNodeStorage<FirFunction, FunctionExitNode> = SymbolBasedNodeStorage()
|
private val exitTargetsForReturn: SymbolBasedNodeStorage<FirFunction, FunctionExitNode> = SymbolBasedNodeStorage()
|
||||||
@@ -122,22 +110,17 @@ class ControlFlowGraphBuilder {
|
|||||||
return nonDirectJumps[exitNode].mapNotNullTo(returnValues) { it.returnExpression() }
|
return nonDirectJumps[exitNode].mapNotNullTo(returnValues) { it.returnExpression() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(CfgBuilderInternals::class)
|
|
||||||
fun isTopLevel(): Boolean = graphs.size == 1
|
fun isTopLevel(): Boolean = graphs.size == 1
|
||||||
|
|
||||||
// ----------------------------------- Utils -----------------------------------
|
// ----------------------------------- Utils -----------------------------------
|
||||||
|
|
||||||
@OptIn(CfgBuilderInternals::class)
|
private fun pushGraph(graph: ControlFlowGraph) {
|
||||||
private fun pushGraph(graph: ControlFlowGraph, mode: Mode) {
|
|
||||||
graphs.push(graph)
|
graphs.push(graph)
|
||||||
modes.push(mode)
|
|
||||||
levelCounter++
|
levelCounter++
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(CfgBuilderInternals::class)
|
|
||||||
private fun popGraph(): ControlFlowGraph {
|
private fun popGraph(): ControlFlowGraph {
|
||||||
levelCounter--
|
levelCounter--
|
||||||
modes.pop()
|
|
||||||
return graphs.pop().also { it.complete() }
|
return graphs.pop().also { it.complete() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,32 +136,24 @@ class ControlFlowGraphBuilder {
|
|||||||
}
|
}
|
||||||
val graph = ControlFlowGraph(function, name, ControlFlowGraph.Kind.Function)
|
val graph = ControlFlowGraph(function, name, ControlFlowGraph.Kind.Function)
|
||||||
// function is local
|
// function is local
|
||||||
val localFunctionNode = runIf(mode == Mode.Body) {
|
val localFunctionNode = runIf(function.symbol.callableId.isLocal && currentGraph.kind.withBody) {
|
||||||
assert(currentGraph.kind.withBody)
|
|
||||||
currentGraph.addSubGraph(graph)
|
currentGraph.addSubGraph(graph)
|
||||||
|
|
||||||
createLocalFunctionDeclarationNode(function).also {
|
createLocalFunctionDeclarationNode(function).also {
|
||||||
addNewSimpleNode(it)
|
addNewSimpleNode(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pushGraph(
|
pushGraph(graph)
|
||||||
graph = graph,
|
|
||||||
mode = Mode.Body
|
|
||||||
)
|
|
||||||
|
|
||||||
val previousNode = enterToLocalClassesMembers[function.symbol]
|
|
||||||
?: (function as? FirSimpleFunction)?.takeIf { it.isLocal }?.let { lastNode }
|
|
||||||
|
|
||||||
val enterNode = createFunctionEnterNode(function).also {
|
val enterNode = createFunctionEnterNode(function).also {
|
||||||
lastNodes.push(it)
|
lastNodes.push(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (previousNode != null) {
|
if (localFunctionNode != null) {
|
||||||
if (localFunctionNode == previousNode) {
|
addEdge(localFunctionNode, enterNode)
|
||||||
addEdge(localFunctionNode, enterNode, preferredKind = EdgeKind.Forward)
|
} else {
|
||||||
} else {
|
enterToLocalClassesMembers[function.symbol]?.let {
|
||||||
addEdge(previousNode, enterNode, preferredKind = EdgeKind.DfgForward)
|
addEdge(it, enterNode, preferredKind = EdgeKind.DfgForward)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,7 +239,7 @@ class ControlFlowGraphBuilder {
|
|||||||
fun enterAnonymousFunction(anonymousFunction: FirAnonymousFunction): FunctionEnterNode {
|
fun enterAnonymousFunction(anonymousFunction: FirAnonymousFunction): FunctionEnterNode {
|
||||||
val symbol = anonymousFunction.symbol
|
val symbol = anonymousFunction.symbol
|
||||||
val flowSourceNode = postponedAnonymousFunctionNodes.getValue(symbol).first
|
val flowSourceNode = postponedAnonymousFunctionNodes.getValue(symbol).first
|
||||||
pushGraph(ControlFlowGraph(anonymousFunction, "<anonymous>", ControlFlowGraph.Kind.AnonymousFunction), Mode.Function)
|
pushGraph(ControlFlowGraph(anonymousFunction, "<anonymous>", ControlFlowGraph.Kind.AnonymousFunction))
|
||||||
val enterNode = createFunctionEnterNode(anonymousFunction)
|
val enterNode = createFunctionEnterNode(anonymousFunction)
|
||||||
val exitNode = createFunctionExitNode(anonymousFunction)
|
val exitNode = createFunctionExitNode(anonymousFunction)
|
||||||
exitTargetsForReturn.push(exitNode)
|
exitTargetsForReturn.push(exitNode)
|
||||||
@@ -401,10 +376,7 @@ class ControlFlowGraphBuilder {
|
|||||||
// ----------------------------------- Classes -----------------------------------
|
// ----------------------------------- Classes -----------------------------------
|
||||||
|
|
||||||
fun enterClass() {
|
fun enterClass() {
|
||||||
pushGraph(
|
pushGraph(ControlFlowGraph(null, "STUB_CLASS_GRAPH", ControlFlowGraph.Kind.Stub))
|
||||||
ControlFlowGraph(null, "STUB_CLASS_GRAPH", ControlFlowGraph.Kind.Stub),
|
|
||||||
mode = Mode.ClassInitializer
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun exitClass() {
|
fun exitClass() {
|
||||||
@@ -433,8 +405,7 @@ class ControlFlowGraphBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val classGraph = ControlFlowGraph(klass, name, ControlFlowGraph.Kind.ClassInitializer)
|
pushGraph(ControlFlowGraph(klass, name, ControlFlowGraph.Kind.ClassInitializer))
|
||||||
pushGraph(classGraph, Mode.ClassInitializer)
|
|
||||||
val exitNode = createClassExitNode(klass)
|
val exitNode = createClassExitNode(klass)
|
||||||
var node: CFGNode<*> = createClassEnterNode(klass)
|
var node: CFGNode<*> = createClassEnterNode(klass)
|
||||||
var prevInitPartNode: CFGNode<*>? = null
|
var prevInitPartNode: CFGNode<*>? = null
|
||||||
@@ -529,10 +500,7 @@ class ControlFlowGraphBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun enterScript(script: FirScript): ScriptEnterNode {
|
fun enterScript(script: FirScript): ScriptEnterNode {
|
||||||
pushGraph(
|
pushGraph(ControlFlowGraph(null, "SCRIPT_GRAPH", ControlFlowGraph.Kind.Function))
|
||||||
ControlFlowGraph(null, "SCRIPT_GRAPH", ControlFlowGraph.Kind.Function),
|
|
||||||
mode = Mode.Body
|
|
||||||
)
|
|
||||||
val enterNode = createScriptEnterNode(script)
|
val enterNode = createScriptEnterNode(script)
|
||||||
lastNodes.push(enterNode)
|
lastNodes.push(enterNode)
|
||||||
return enterNode
|
return enterNode
|
||||||
@@ -550,8 +518,7 @@ class ControlFlowGraphBuilder {
|
|||||||
if (valueParameter.defaultValue == null) return null
|
if (valueParameter.defaultValue == null) return null
|
||||||
|
|
||||||
val outerEnterNode = createEnterValueParameterNode(valueParameter)
|
val outerEnterNode = createEnterValueParameterNode(valueParameter)
|
||||||
val graph = ControlFlowGraph(valueParameter, "default value of ${valueParameter.name}", ControlFlowGraph.Kind.DefaultArgument)
|
pushGraph(ControlFlowGraph(valueParameter, "default value of ${valueParameter.name}", ControlFlowGraph.Kind.DefaultArgument))
|
||||||
pushGraph(graph, Mode.Body)
|
|
||||||
val innerExitNode = createExitDefaultArgumentsNode(valueParameter)
|
val innerExitNode = createExitDefaultArgumentsNode(valueParameter)
|
||||||
val innerEnterNode = createEnterDefaultArgumentsNode(valueParameter)
|
val innerEnterNode = createEnterDefaultArgumentsNode(valueParameter)
|
||||||
addNewSimpleNode(outerEnterNode)
|
addNewSimpleNode(outerEnterNode)
|
||||||
@@ -599,8 +566,7 @@ class ControlFlowGraphBuilder {
|
|||||||
fun enterProperty(property: FirProperty): PropertyInitializerEnterNode? {
|
fun enterProperty(property: FirProperty): PropertyInitializerEnterNode? {
|
||||||
if (!property.hasInitialization) return null
|
if (!property.hasInitialization) return null
|
||||||
|
|
||||||
val graph = ControlFlowGraph(property, "val ${property.name}", ControlFlowGraph.Kind.PropertyInitializer)
|
pushGraph(ControlFlowGraph(property, "val ${property.name}", ControlFlowGraph.Kind.PropertyInitializer))
|
||||||
pushGraph(graph, Mode.PropertyInitializer)
|
|
||||||
|
|
||||||
val enterNode = createPropertyInitializerEnterNode(property)
|
val enterNode = createPropertyInitializerEnterNode(property)
|
||||||
val exitNode = createPropertyInitializerExitNode(property)
|
val exitNode = createPropertyInitializerExitNode(property)
|
||||||
@@ -628,8 +594,7 @@ class ControlFlowGraphBuilder {
|
|||||||
fun enterField(field: FirField): FieldInitializerEnterNode? {
|
fun enterField(field: FirField): FieldInitializerEnterNode? {
|
||||||
if (field.initializer == null) return null
|
if (field.initializer == null) return null
|
||||||
|
|
||||||
val graph = ControlFlowGraph(field, "val ${field.name}", ControlFlowGraph.Kind.FieldInitializer)
|
pushGraph(ControlFlowGraph(field, "val ${field.name}", ControlFlowGraph.Kind.FieldInitializer))
|
||||||
pushGraph(graph, Mode.FieldInitializer)
|
|
||||||
|
|
||||||
val enterNode = createFieldInitializerEnterNode(field)
|
val enterNode = createFieldInitializerEnterNode(field)
|
||||||
val exitNode = createFieldInitializerExitNode(field)
|
val exitNode = createFieldInitializerExitNode(field)
|
||||||
@@ -1235,8 +1200,7 @@ class ControlFlowGraphBuilder {
|
|||||||
// ----------------------------------- Annotations -----------------------------------
|
// ----------------------------------- Annotations -----------------------------------
|
||||||
|
|
||||||
fun enterAnnotation(annotation: FirAnnotation): AnnotationEnterNode {
|
fun enterAnnotation(annotation: FirAnnotation): AnnotationEnterNode {
|
||||||
val graph = ControlFlowGraph(null, "STUB_GRAPH_FOR_ANNOTATION_CALL", ControlFlowGraph.Kind.AnnotationCall)
|
pushGraph(ControlFlowGraph(null, "STUB_GRAPH_FOR_ANNOTATION_CALL", ControlFlowGraph.Kind.AnnotationCall))
|
||||||
pushGraph(graph, Mode.Body)
|
|
||||||
return createAnnotationEnterNode(annotation).also {
|
return createAnnotationEnterNode(annotation).also {
|
||||||
lastNodes.push(it)
|
lastNodes.push(it)
|
||||||
}
|
}
|
||||||
@@ -1264,8 +1228,7 @@ class ControlFlowGraphBuilder {
|
|||||||
fun enterInitBlock(initBlock: FirAnonymousInitializer): InitBlockEnterNode {
|
fun enterInitBlock(initBlock: FirAnonymousInitializer): InitBlockEnterNode {
|
||||||
// TODO: questionable moment that we should pass data flow from init to init
|
// TODO: questionable moment that we should pass data flow from init to init
|
||||||
|
|
||||||
val graph = ControlFlowGraph(initBlock, "init block", ControlFlowGraph.Kind.Function)
|
pushGraph(ControlFlowGraph(initBlock, "init block", ControlFlowGraph.Kind.Function))
|
||||||
pushGraph(graph, Mode.Body)
|
|
||||||
val enterNode = createInitBlockEnterNode(initBlock).also {
|
val enterNode = createInitBlockEnterNode(initBlock).also {
|
||||||
lastNodes.push(it)
|
lastNodes.push(it)
|
||||||
}
|
}
|
||||||
@@ -1377,7 +1340,7 @@ class ControlFlowGraphBuilder {
|
|||||||
// ----------------------------------- Contract description -----------------------------------
|
// ----------------------------------- Contract description -----------------------------------
|
||||||
|
|
||||||
fun enterContractDescription(): CFGNode<*> {
|
fun enterContractDescription(): CFGNode<*> {
|
||||||
pushGraph(ControlFlowGraph(null, "contract description", ControlFlowGraph.Kind.TopLevel), Mode.Body)
|
pushGraph(ControlFlowGraph(null, "contract description", ControlFlowGraph.Kind.AnonymousFunction))
|
||||||
|
|
||||||
return createContractDescriptionEnterNode().also {
|
return createContractDescriptionEnterNode().also {
|
||||||
lastNodes.push(it)
|
lastNodes.push(it)
|
||||||
|
|||||||
+3
-3
@@ -73,13 +73,13 @@ class ControlFlowGraph(val declaration: FirDeclaration?, val name: String, val k
|
|||||||
enum class Kind(val withBody: Boolean) {
|
enum class Kind(val withBody: Boolean) {
|
||||||
Function(withBody = true),
|
Function(withBody = true),
|
||||||
AnonymousFunction(withBody = true),
|
AnonymousFunction(withBody = true),
|
||||||
ClassInitializer(withBody = true),
|
ClassInitializer(withBody = false),
|
||||||
PropertyInitializer(withBody = true),
|
PropertyInitializer(withBody = true),
|
||||||
FieldInitializer(withBody = true),
|
FieldInitializer(withBody = true),
|
||||||
TopLevel(withBody = false),
|
TopLevel(withBody = false),
|
||||||
AnnotationCall(withBody = true),
|
AnnotationCall(withBody = true),
|
||||||
DefaultArgument(withBody = false),
|
DefaultArgument(withBody = true),
|
||||||
Stub(withBody = true)
|
Stub(withBody = false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user