[FIR] Pass flow to right operand of && expression

This commit is contained in:
Dmitriy Novozhilov
2019-08-28 12:41:07 +03:00
parent 59205cac13
commit 163c5d699f
12 changed files with 694 additions and 577 deletions
@@ -488,7 +488,9 @@ class FirDataFlowAnalyzerImpl(transformer: FirBodyResolveTransformer) : FirDataF
} }
override fun exitLeftBinaryAndArgument(binaryLogicExpression: FirBinaryLogicExpression) { override fun exitLeftBinaryAndArgument(binaryLogicExpression: FirBinaryLogicExpression) {
graphBuilder.exitLeftBinaryAndArgument(binaryLogicExpression) val node = graphBuilder.exitLeftBinaryAndArgument(binaryLogicExpression).passFlow(false)
val leftOperandVariable = getVariable(node.previousNodes.first().fir)
node.flow = logicSystem.approveFactsInsideFlow(leftOperandVariable eq True, node.flow).also { it.freeze() }
} }
override fun exitBinaryAnd(binaryLogicExpression: FirBinaryLogicExpression) { override fun exitBinaryAnd(binaryLogicExpression: FirBinaryLogicExpression) {
@@ -99,10 +99,10 @@ abstract class AbstractBinaryExitNode<T : FirElement>(owner: ControlFlowGraph, l
} }
class BinaryAndEnterNode(owner: ControlFlowGraph, override val fir: FirBinaryLogicExpression, level: Int) : CFGNode<FirBinaryLogicExpression>(owner, level) class BinaryAndEnterNode(owner: ControlFlowGraph, override val fir: FirBinaryLogicExpression, level: Int) : CFGNode<FirBinaryLogicExpression>(owner, level)
class BinaryAndExitLeftOperandNode(owner: ControlFlowGraph, override val fir: FirBinaryLogicExpression, level: Int) : CFGNode<FirBinaryLogicExpression>(owner, level)
class BinaryAndExitNode(owner: ControlFlowGraph, override val fir: FirBinaryLogicExpression, level: Int) : AbstractBinaryExitNode<FirBinaryLogicExpression>(owner, level) class BinaryAndExitNode(owner: ControlFlowGraph, override val fir: FirBinaryLogicExpression, level: Int) : AbstractBinaryExitNode<FirBinaryLogicExpression>(owner, level)
class BinaryOrEnterNode(owner: ControlFlowGraph, override val fir: FirBinaryLogicExpression, level: Int) : CFGNode<FirBinaryLogicExpression>(owner, level)
// Exit left node pass after left argument in case if that argument is `false` class BinaryOrEnterNode(owner: ControlFlowGraph, override val fir: FirBinaryLogicExpression, level: Int) : CFGNode<FirBinaryLogicExpression>(owner, level)
class BinaryOrExitLeftOperandNode(owner: ControlFlowGraph, override val fir: FirBinaryLogicExpression, level: Int) : CFGNode<FirBinaryLogicExpression>(owner, level) class BinaryOrExitLeftOperandNode(owner: ControlFlowGraph, override val fir: FirBinaryLogicExpression, level: Int) : CFGNode<FirBinaryLogicExpression>(owner, level)
class BinaryOrExitNode(owner: ControlFlowGraph, override val fir: FirBinaryLogicExpression, level: Int) : AbstractBinaryExitNode<FirBinaryLogicExpression>(owner, level) class BinaryOrExitNode(owner: ControlFlowGraph, override val fir: FirBinaryLogicExpression, level: Int) : AbstractBinaryExitNode<FirBinaryLogicExpression>(owner, level)
@@ -303,9 +303,15 @@ class ControlFlowGraphBuilder : ControlFlowGraphNodeBuilder() {
return createBinaryAndEnterNode(binaryLogicExpression).also { addNewSimpleNode(it) }.also { levelCounter++ } return createBinaryAndEnterNode(binaryLogicExpression).also { addNewSimpleNode(it) }.also { levelCounter++ }
} }
fun exitLeftBinaryAndArgument(binaryLogicExpression: FirBinaryLogicExpression) { fun exitLeftBinaryAndArgument(binaryLogicExpression: FirBinaryLogicExpression): BinaryAndExitLeftOperandNode {
assert(binaryLogicExpression.kind == FirBinaryLogicExpression.OperationKind.AND) assert(binaryLogicExpression.kind == FirBinaryLogicExpression.OperationKind.AND)
addEdge(lastNode, binaryAndExitNodes.top(), propagateDeadness = false, isDead = lastNode.booleanConstValue == true) val lastNode = lastNodes.pop()
val leftBooleanConstValue = lastNode.booleanConstValue
addEdge(lastNode, binaryAndExitNodes.top(), propagateDeadness = false, isDead = leftBooleanConstValue == true)
return createBinaryAndExitLeftOperandNode(binaryLogicExpression).also {
addEdge(lastNode, it, isDead = leftBooleanConstValue == false)
lastNodes.push(it)
}
} }
fun exitBinaryAnd(binaryLogicExpression: FirBinaryLogicExpression): BinaryAndExitNode { fun exitBinaryAnd(binaryLogicExpression: FirBinaryLogicExpression): BinaryAndExitNode {
@@ -158,4 +158,7 @@ abstract class ControlFlowGraphNodeBuilder {
protected fun createTryExpressionExitNode(fir: FirTryExpression): TryExpressionExitNode = protected fun createTryExpressionExitNode(fir: FirTryExpression): TryExpressionExitNode =
TryExpressionExitNode(graph, fir, levelCounter) TryExpressionExitNode(graph, fir, levelCounter)
protected fun createBinaryAndExitLeftOperandNode(fir: FirBinaryLogicExpression): BinaryAndExitLeftOperandNode =
BinaryAndExitLeftOperandNode(graph, fir, levelCounter)
} }
@@ -133,6 +133,7 @@ fun CFGNode<*>.render(): String =
is TryExpressionExitNode -> "Try expression exit" is TryExpressionExitNode -> "Try expression exit"
is BinaryAndEnterNode -> "Enter &&" is BinaryAndEnterNode -> "Enter &&"
is BinaryAndExitLeftOperandNode -> "Exit left part of &&"
is BinaryAndExitNode -> "Exit &&" is BinaryAndExitNode -> "Exit &&"
is BinaryOrEnterNode -> "Enter ||" is BinaryOrEnterNode -> "Enter ||"
is BinaryOrExitLeftOperandNode -> "Exit left part of ||" is BinaryOrExitLeftOperandNode -> "Exit left part of ||"
@@ -55,148 +55,154 @@ subgraph test_2 {
25 [shape=box label="Enter when branch condition "]; 25 [shape=box label="Enter when branch condition "];
26 [shape=box label="Enter &&"]; 26 [shape=box label="Enter &&"];
27 [shape=box label="Access variable R|<local>/b1|"]; 27 [shape=box label="Access variable R|<local>/b1|"];
28 [shape=box label="Access variable R|<local>/b2|"]; 28 [shape=box label="Exit left part of &&"];
29 [shape=box label="Exit &&"]; 29 [shape=box label="Access variable R|<local>/b2|"];
30 [shape=box label="Exit when branch condition"]; 30 [shape=box label="Exit &&"];
31 [shape=box label="Enter block"]; 31 [shape=box label="Exit when branch condition"];
32 [shape=box label="Const: Int(1)"]; 32 [shape=box label="Enter block"];
33 [shape=box label="Exit block"]; 33 [shape=box label="Const: Int(1)"];
34 [shape=box label="Exit when branch result"]; 34 [shape=box label="Exit block"];
35 [shape=box label="Enter when branch condition else"]; 35 [shape=box label="Exit when branch result"];
36 [shape=box label="Exit when branch condition"]; 36 [shape=box label="Enter when branch condition else"];
37 [shape=box label="Enter block"]; 37 [shape=box label="Exit when branch condition"];
38 [shape=box label="Exit block"]; 38 [shape=box label="Enter block"];
39 [shape=box label="Exit when branch result"]; 39 [shape=box label="Exit block"];
40 [shape=box label="Exit when"]; 40 [shape=box label="Exit when branch result"];
41 [shape=box label="Exit block"]; 41 [shape=box label="Exit when"];
42 [shape=box label="Exit function test_2"]; 42 [shape=box label="Exit block"];
43 [shape=box label="Exit function test_2"];
22 -> {23}; 22 -> {23};
23 -> {24}; 23 -> {24};
24 -> {25}; 24 -> {25};
25 -> {26}; 25 -> {26};
26 -> {27}; 26 -> {27};
27 -> {29 28}; 27 -> {30 28};
28 -> {29}; 28 -> {29};
29 -> {30}; 29 -> {30};
30 -> {31 35}; 30 -> {31};
31 -> {32}; 31 -> {32 36};
32 -> {33}; 32 -> {33};
33 -> {34}; 33 -> {34};
34 -> {40}; 34 -> {35};
35 -> {36}; 35 -> {41};
36 -> {37}; 36 -> {37};
37 -> {38}; 37 -> {38};
38 -> {39}; 38 -> {39};
39 -> {40}; 39 -> {40};
40 -> {41}; 40 -> {41};
41 -> {42}; 41 -> {42};
42 -> {43};
} }
subgraph test_3 { subgraph test_3 {
43 [shape=box label="Enter function test_3"]; 44 [shape=box label="Enter function test_3"];
44 [shape=box label="Enter block"]; 45 [shape=box label="Enter block"];
45 [shape=box label="Enter when"]; 46 [shape=box label="Enter when"];
46 [shape=box label="Enter when branch condition "]; 47 [shape=box label="Enter when branch condition "];
47 [shape=box label="Enter ||"]; 48 [shape=box label="Enter ||"];
48 [shape=box label="Enter &&"]; 49 [shape=box label="Enter &&"];
49 [shape=box label="Access variable R|<local>/b1|"]; 50 [shape=box label="Access variable R|<local>/b1|"];
50 [shape=box label="Access variable R|<local>/b2|"]; 51 [shape=box label="Exit left part of &&"];
51 [shape=box label="Exit &&"]; 52 [shape=box label="Access variable R|<local>/b2|"];
52 [shape=box label="Exit left part of ||"]; 53 [shape=box label="Exit &&"];
53 [shape=box label="Access variable R|<local>/b3|"]; 54 [shape=box label="Exit left part of ||"];
54 [shape=box label="Exit ||"]; 55 [shape=box label="Access variable R|<local>/b3|"];
55 [shape=box label="Exit when branch condition"]; 56 [shape=box label="Exit ||"];
56 [shape=box label="Enter block"]; 57 [shape=box label="Exit when branch condition"];
57 [shape=box label="Const: Int(1)"]; 58 [shape=box label="Enter block"];
58 [shape=box label="Exit block"]; 59 [shape=box label="Const: Int(1)"];
59 [shape=box label="Exit when branch result"]; 60 [shape=box label="Exit block"];
60 [shape=box label="Enter when branch condition else"]; 61 [shape=box label="Exit when branch result"];
61 [shape=box label="Exit when branch condition"]; 62 [shape=box label="Enter when branch condition else"];
62 [shape=box label="Enter block"]; 63 [shape=box label="Exit when branch condition"];
63 [shape=box label="Exit block"]; 64 [shape=box label="Enter block"];
64 [shape=box label="Exit when branch result"]; 65 [shape=box label="Exit block"];
65 [shape=box label="Exit when"]; 66 [shape=box label="Exit when branch result"];
66 [shape=box label="Exit block"]; 67 [shape=box label="Exit when"];
67 [shape=box label="Exit function test_3"]; 68 [shape=box label="Exit block"];
69 [shape=box label="Exit function test_3"];
43 -> {44};
44 -> {45}; 44 -> {45};
45 -> {46}; 45 -> {46};
46 -> {47}; 46 -> {47};
47 -> {48}; 47 -> {48};
48 -> {49}; 48 -> {49};
49 -> {51 50}; 49 -> {50};
50 -> {51}; 50 -> {53 51};
51 -> {54 52}; 51 -> {52};
52 -> {53}; 52 -> {53};
53 -> {54}; 53 -> {56 54};
54 -> {55}; 54 -> {55};
55 -> {56 60}; 55 -> {56};
56 -> {57}; 56 -> {57};
57 -> {58}; 57 -> {58 62};
58 -> {59}; 58 -> {59};
59 -> {65}; 59 -> {60};
60 -> {61}; 60 -> {61};
61 -> {62}; 61 -> {67};
62 -> {63}; 62 -> {63};
63 -> {64}; 63 -> {64};
64 -> {65}; 64 -> {65};
65 -> {66}; 65 -> {66};
66 -> {67}; 66 -> {67};
67 -> {68};
68 -> {69};
} }
subgraph test_4 { subgraph test_4 {
68 [shape=box label="Enter function test_4"]; 70 [shape=box label="Enter function test_4"];
69 [shape=box label="Enter block"]; 71 [shape=box label="Enter block"];
70 [shape=box label="Enter when"]; 72 [shape=box label="Enter when"];
71 [shape=box label="Enter when branch condition "]; 73 [shape=box label="Enter when branch condition "];
72 [shape=box label="Enter ||"]; 74 [shape=box label="Enter ||"];
73 [shape=box label="Access variable R|<local>/b1|"]; 75 [shape=box label="Access variable R|<local>/b1|"];
74 [shape=box label="Exit left part of ||"]; 76 [shape=box label="Exit left part of ||"];
75 [shape=box label="Enter &&"]; 77 [shape=box label="Enter &&"];
76 [shape=box label="Access variable R|<local>/b2|"]; 78 [shape=box label="Access variable R|<local>/b2|"];
77 [shape=box label="Access variable R|<local>/b3|"]; 79 [shape=box label="Exit left part of &&"];
78 [shape=box label="Exit &&"]; 80 [shape=box label="Access variable R|<local>/b3|"];
79 [shape=box label="Exit ||"]; 81 [shape=box label="Exit &&"];
80 [shape=box label="Exit when branch condition"]; 82 [shape=box label="Exit ||"];
81 [shape=box label="Enter block"]; 83 [shape=box label="Exit when branch condition"];
82 [shape=box label="Const: Int(1)"]; 84 [shape=box label="Enter block"];
83 [shape=box label="Exit block"]; 85 [shape=box label="Const: Int(1)"];
84 [shape=box label="Exit when branch result"]; 86 [shape=box label="Exit block"];
85 [shape=box label="Enter when branch condition else"]; 87 [shape=box label="Exit when branch result"];
86 [shape=box label="Exit when branch condition"]; 88 [shape=box label="Enter when branch condition else"];
87 [shape=box label="Enter block"]; 89 [shape=box label="Exit when branch condition"];
88 [shape=box label="Exit block"]; 90 [shape=box label="Enter block"];
89 [shape=box label="Exit when branch result"];
90 [shape=box label="Exit when"];
91 [shape=box label="Exit block"]; 91 [shape=box label="Exit block"];
92 [shape=box label="Exit function test_4"]; 92 [shape=box label="Exit when branch result"];
93 [shape=box label="Exit when"];
94 [shape=box label="Exit block"];
95 [shape=box label="Exit function test_4"];
68 -> {69};
69 -> {70};
70 -> {71}; 70 -> {71};
71 -> {72}; 71 -> {72};
72 -> {73}; 72 -> {73};
73 -> {79 74}; 73 -> {74};
74 -> {75}; 74 -> {75};
75 -> {76}; 75 -> {82 76};
76 -> {78 77}; 76 -> {77};
77 -> {78}; 77 -> {78};
78 -> {79}; 78 -> {81 79};
79 -> {80}; 79 -> {80};
80 -> {81 85}; 80 -> {81};
81 -> {82}; 81 -> {82};
82 -> {83}; 82 -> {83};
83 -> {84}; 83 -> {84 88};
84 -> {90}; 84 -> {85};
85 -> {86}; 85 -> {86};
86 -> {87}; 86 -> {87};
87 -> {88}; 87 -> {93};
88 -> {89}; 88 -> {89};
89 -> {90}; 89 -> {90};
90 -> {91}; 90 -> {91};
91 -> {92}; 91 -> {92};
92 -> {93};
93 -> {94};
94 -> {95};
} }
} }
@@ -202,182 +202,193 @@ subgraph test_5 {
93 [shape=box label="Enter when branch condition "]; 93 [shape=box label="Enter when branch condition "];
94 [shape=box label="Enter &&"]; 94 [shape=box label="Enter &&"];
95 [shape=box label="Access variable R|<local>/b|"]; 95 [shape=box label="Access variable R|<local>/b|"];
96 [shape=box label="Const: Boolean(false)"]; 96 [shape=box label="Exit left part of &&"];
97 [shape=box label="Exit &&"]; 97 [shape=box label="Const: Boolean(false)"];
98 [shape=box label="Exit when branch condition"]; 98 [shape=box label="Exit &&"];
99 [shape=box label="Enter block"]; 99 [shape=box label="Exit when branch condition"];
100 [shape=box label="Const: Int(1)"]; 100 [shape=box label="Enter block"];
101 [shape=box label="Exit block"]; 101 [shape=box label="Const: Int(1)"];
102 [shape=box label="Exit when branch result"]; 102 [shape=box label="Exit block"];
103 [shape=box label="Enter when branch condition else"]; 103 [shape=box label="Exit when branch result"];
104 [shape=box label="Exit when branch condition"]; 104 [shape=box label="Enter when branch condition else"];
105 [shape=box label="Enter block"]; 105 [shape=box label="Exit when branch condition"];
106 [shape=box label="Exit block"]; 106 [shape=box label="Enter block"];
107 [shape=box label="Exit when branch result"]; 107 [shape=box label="Exit block"];
108 [shape=box label="Exit when"]; 108 [shape=box label="Exit when branch result"];
109 [shape=box label="Exit block"]; 109 [shape=box label="Exit when"];
110 [shape=box label="Exit function test_5"]; 110 [shape=box label="Exit block"];
111 [shape=box label="Exit function test_5"];
90 -> {91}; 90 -> {91};
91 -> {92}; 91 -> {92};
92 -> {93}; 92 -> {93};
93 -> {94}; 93 -> {94};
94 -> {95}; 94 -> {95};
95 -> {97 96}; 95 -> {98 96};
96 -> {97}; 96 -> {97};
97 -> {98}; 97 -> {98};
98 -> {99 103}; 98 -> {99};
99 -> {100}; 99 -> {100 104};
100 -> {101}; 100 -> {101};
101 -> {102}; 101 -> {102};
102 -> {108}; 102 -> {103};
103 -> {104}; 103 -> {109};
104 -> {105}; 104 -> {105};
105 -> {106}; 105 -> {106};
106 -> {107}; 106 -> {107};
107 -> {108}; 107 -> {108};
108 -> {109}; 108 -> {109};
109 -> {110}; 109 -> {110};
110 -> {111};
} }
subgraph test_6 { subgraph test_6 {
111 [shape=box label="Enter function test_6"]; 112 [shape=box label="Enter function test_6"];
112 [shape=box label="Enter block"]; 113 [shape=box label="Enter block"];
113 [shape=box label="Enter when"]; 114 [shape=box label="Enter when"];
114 [shape=box label="Enter when branch condition "]; 115 [shape=box label="Enter when branch condition "];
115 [shape=box label="Enter &&"]; 116 [shape=box label="Enter &&"];
116 [shape=box label="Const: Boolean(false)"]; 117 [shape=box label="Const: Boolean(false)"];
117 [shape=box label="Access variable R|<local>/b|"];
118 [shape=box label="Stub[DEAD]"]; 118 [shape=box label="Stub[DEAD]"];
119 [shape=box label="Exit &&"]; 119 [shape=box label="Exit left part of &&[DEAD]"];
120 [shape=box label="Exit when branch condition"]; 120 [shape=box label="Access variable R|<local>/b|[DEAD]"];
121 [shape=box label="Enter block"]; 121 [shape=box label="Stub[DEAD]"];
122 [shape=box label="Const: Int(1)"]; 122 [shape=box label="Exit &&"];
123 [shape=box label="Exit block"]; 123 [shape=box label="Exit when branch condition"];
124 [shape=box label="Exit when branch result"]; 124 [shape=box label="Enter block"];
125 [shape=box label="Enter when branch condition else"]; 125 [shape=box label="Const: Int(1)"];
126 [shape=box label="Exit when branch condition"]; 126 [shape=box label="Exit block"];
127 [shape=box label="Enter block"]; 127 [shape=box label="Exit when branch result"];
128 [shape=box label="Exit block"]; 128 [shape=box label="Enter when branch condition else"];
129 [shape=box label="Exit when branch result"]; 129 [shape=box label="Exit when branch condition"];
130 [shape=box label="Exit when"]; 130 [shape=box label="Enter block"];
131 [shape=box label="Exit block"]; 131 [shape=box label="Exit block"];
132 [shape=box label="Exit function test_6"]; 132 [shape=box label="Exit when branch result"];
133 [shape=box label="Exit when"];
134 [shape=box label="Exit block"];
135 [shape=box label="Exit function test_6"];
111 -> {112};
112 -> {113}; 112 -> {113};
113 -> {114}; 113 -> {114};
114 -> {115}; 114 -> {115};
115 -> {116}; 115 -> {116};
116 -> {119 117}; 116 -> {117};
117 -> {122};
117 -> {118} [style=dotted]; 117 -> {118} [style=dotted];
118 -> {119} [style=dotted]; 118 -> {119} [style=dotted];
119 -> {120}; 119 -> {120} [style=dotted];
120 -> {121 125}; 120 -> {121} [style=dotted];
121 -> {122}; 121 -> {122} [style=dotted];
122 -> {123}; 122 -> {123};
123 -> {124}; 123 -> {124 128};
124 -> {130}; 124 -> {125};
125 -> {126}; 125 -> {126};
126 -> {127}; 126 -> {127};
127 -> {128}; 127 -> {133};
128 -> {129}; 128 -> {129};
129 -> {130}; 129 -> {130};
130 -> {131}; 130 -> {131};
131 -> {132}; 131 -> {132};
132 -> {133};
133 -> {134};
134 -> {135};
} }
subgraph test_7 { subgraph test_7 {
133 [shape=box label="Enter function test_7"]; 136 [shape=box label="Enter function test_7"];
134 [shape=box label="Enter block"]; 137 [shape=box label="Enter block"];
135 [shape=box label="Enter when"]; 138 [shape=box label="Enter when"];
136 [shape=box label="Enter when branch condition "]; 139 [shape=box label="Enter when branch condition "];
137 [shape=box label="Enter &&"]; 140 [shape=box label="Enter &&"];
138 [shape=box label="Access variable R|<local>/b|"]; 141 [shape=box label="Access variable R|<local>/b|"];
139 [shape=box label="Const: Boolean(true)"]; 142 [shape=box label="Exit left part of &&"];
140 [shape=box label="Exit &&"]; 143 [shape=box label="Const: Boolean(true)"];
141 [shape=box label="Exit when branch condition"]; 144 [shape=box label="Exit &&"];
142 [shape=box label="Enter block"]; 145 [shape=box label="Exit when branch condition"];
143 [shape=box label="Const: Int(1)"]; 146 [shape=box label="Enter block"];
144 [shape=box label="Exit block"]; 147 [shape=box label="Const: Int(1)"];
145 [shape=box label="Exit when branch result"]; 148 [shape=box label="Exit block"];
146 [shape=box label="Enter when branch condition else"]; 149 [shape=box label="Exit when branch result"];
147 [shape=box label="Exit when branch condition"]; 150 [shape=box label="Enter when branch condition else"];
148 [shape=box label="Enter block"]; 151 [shape=box label="Exit when branch condition"];
149 [shape=box label="Exit block"]; 152 [shape=box label="Enter block"];
150 [shape=box label="Exit when branch result"]; 153 [shape=box label="Exit block"];
151 [shape=box label="Exit when"]; 154 [shape=box label="Exit when branch result"];
152 [shape=box label="Exit block"]; 155 [shape=box label="Exit when"];
153 [shape=box label="Exit function test_7"]; 156 [shape=box label="Exit block"];
157 [shape=box label="Exit function test_7"];
133 -> {134};
134 -> {135};
135 -> {136};
136 -> {137}; 136 -> {137};
137 -> {138}; 137 -> {138};
138 -> {140 139}; 138 -> {139};
139 -> {140}; 139 -> {140};
140 -> {141}; 140 -> {141};
141 -> {142 146}; 141 -> {144 142};
142 -> {143}; 142 -> {143};
143 -> {144}; 143 -> {144};
144 -> {145}; 144 -> {145};
145 -> {151}; 145 -> {146 150};
146 -> {147}; 146 -> {147};
147 -> {148}; 147 -> {148};
148 -> {149}; 148 -> {149};
149 -> {150}; 149 -> {155};
150 -> {151}; 150 -> {151};
151 -> {152}; 151 -> {152};
152 -> {153}; 152 -> {153};
} 153 -> {154};
subgraph test_8 {
154 [shape=box label="Enter function test_8"];
155 [shape=box label="Enter block"];
156 [shape=box label="Enter when"];
157 [shape=box label="Enter when branch condition "];
158 [shape=box label="Enter &&"];
159 [shape=box label="Const: Boolean(true)"];
160 [shape=box label="Access variable R|<local>/b|"];
161 [shape=box label="Stub[DEAD]"];
162 [shape=box label="Exit &&"];
163 [shape=box label="Exit when branch condition"];
164 [shape=box label="Enter block"];
165 [shape=box label="Const: Int(1)"];
166 [shape=box label="Exit block"];
167 [shape=box label="Exit when branch result"];
168 [shape=box label="Enter when branch condition else"];
169 [shape=box label="Exit when branch condition"];
170 [shape=box label="Enter block"];
171 [shape=box label="Exit block"];
172 [shape=box label="Exit when branch result"];
173 [shape=box label="Exit when"];
174 [shape=box label="Exit block"];
175 [shape=box label="Exit function test_8"];
154 -> {155}; 154 -> {155};
155 -> {156}; 155 -> {156};
156 -> {157}; 156 -> {157};
157 -> {158}; }
subgraph test_8 {
158 [shape=box label="Enter function test_8"];
159 [shape=box label="Enter block"];
160 [shape=box label="Enter when"];
161 [shape=box label="Enter when branch condition "];
162 [shape=box label="Enter &&"];
163 [shape=box label="Const: Boolean(true)"];
164 [shape=box label="Exit left part of &&"];
165 [shape=box label="Access variable R|<local>/b|"];
166 [shape=box label="Stub[DEAD]"];
167 [shape=box label="Exit &&"];
168 [shape=box label="Exit when branch condition"];
169 [shape=box label="Enter block"];
170 [shape=box label="Const: Int(1)"];
171 [shape=box label="Exit block"];
172 [shape=box label="Exit when branch result"];
173 [shape=box label="Enter when branch condition else"];
174 [shape=box label="Exit when branch condition"];
175 [shape=box label="Enter block"];
176 [shape=box label="Exit block"];
177 [shape=box label="Exit when branch result"];
178 [shape=box label="Exit when"];
179 [shape=box label="Exit block"];
180 [shape=box label="Exit function test_8"];
158 -> {159}; 158 -> {159};
159 -> {160}; 159 -> {160};
159 -> {161} [style=dotted]; 160 -> {161};
160 -> {162}; 161 -> {162};
161 -> {162} [style=dotted];
162 -> {163}; 162 -> {163};
163 -> {164 168}; 163 -> {164};
163 -> {166} [style=dotted];
164 -> {165}; 164 -> {165};
165 -> {166}; 165 -> {167};
166 -> {167}; 166 -> {167} [style=dotted];
167 -> {173}; 167 -> {168};
168 -> {169}; 168 -> {169 173};
169 -> {170}; 169 -> {170};
170 -> {171}; 170 -> {171};
171 -> {172}; 171 -> {172};
172 -> {173}; 172 -> {178};
173 -> {174}; 173 -> {174};
174 -> {175}; 174 -> {175};
175 -> {176};
176 -> {177};
177 -> {178};
178 -> {179};
179 -> {180};
} }
} }
+24 -22
View File
@@ -103,23 +103,24 @@ subgraph test_2 {
49 [shape=box label="Enter &&"]; 49 [shape=box label="Enter &&"];
50 [shape=box label="Access variable R|<local>/x|"]; 50 [shape=box label="Access variable R|<local>/x|"];
51 [shape=box label="Type operator: x is A"]; 51 [shape=box label="Type operator: x is A"];
52 [shape=box label="Access variable R|<local>/x|"]; 52 [shape=box label="Exit left part of &&"];
53 [shape=box label="Type operator: x is B"]; 53 [shape=box label="Access variable R|<local>/x|"];
54 [shape=box label="Exit &&"]; 54 [shape=box label="Type operator: x is B"];
55 [shape=box label="Exit when branch condition"]; 55 [shape=box label="Exit &&"];
56 [shape=box label="Enter block"]; 56 [shape=box label="Exit when branch condition"];
57 [shape=box label="Access variable R|<local>/x|"]; 57 [shape=box label="Enter block"];
58 [shape=box label="Type operator: x is A"]; 58 [shape=box label="Access variable R|<local>/x|"];
59 [shape=box label="Exit block"]; 59 [shape=box label="Type operator: x is A"];
60 [shape=box label="Exit when branch result"]; 60 [shape=box label="Exit block"];
61 [shape=box label="Enter when branch condition else"]; 61 [shape=box label="Exit when branch result"];
62 [shape=box label="Exit when branch condition"]; 62 [shape=box label="Enter when branch condition else"];
63 [shape=box label="Enter block"]; 63 [shape=box label="Exit when branch condition"];
64 [shape=box label="Exit block"]; 64 [shape=box label="Enter block"];
65 [shape=box label="Exit when branch result"]; 65 [shape=box label="Exit block"];
66 [shape=box label="Exit when"]; 66 [shape=box label="Exit when branch result"];
67 [shape=box label="Exit block"]; 67 [shape=box label="Exit when"];
68 [shape=box label="Exit function test_2"]; 68 [shape=box label="Exit block"];
69 [shape=box label="Exit function test_2"];
45 -> {46}; 45 -> {46};
46 -> {47}; 46 -> {47};
@@ -127,23 +128,24 @@ subgraph test_2 {
48 -> {49}; 48 -> {49};
49 -> {50}; 49 -> {50};
50 -> {51}; 50 -> {51};
51 -> {54 52}; 51 -> {55 52};
52 -> {53}; 52 -> {53};
53 -> {54}; 53 -> {54};
54 -> {55}; 54 -> {55};
55 -> {56 61}; 55 -> {56};
56 -> {57}; 56 -> {57 62};
57 -> {58}; 57 -> {58};
58 -> {59}; 58 -> {59};
59 -> {60}; 59 -> {60};
60 -> {66}; 60 -> {61};
61 -> {62}; 61 -> {67};
62 -> {63}; 62 -> {63};
63 -> {64}; 63 -> {64};
64 -> {65}; 64 -> {65};
65 -> {66}; 65 -> {66};
66 -> {67}; 66 -> {67};
67 -> {68}; 67 -> {68};
68 -> {69};
} }
} }
@@ -8,353 +8,415 @@ subgraph foo {
0 -> {1}; 0 -> {1};
} }
subgraph bar { subgraph bool {
2 [shape=box label="Enter function bar"]; 2 [shape=box label="Enter function bool"];
3 [shape=box label="Exit function bar"]; 3 [shape=box label="Exit function bool"];
2 -> {3}; 2 -> {3};
} }
subgraph baz { subgraph bar {
4 [shape=box label="Enter function baz"]; 4 [shape=box label="Enter function bar"];
5 [shape=box label="Exit function baz"]; 5 [shape=box label="Exit function bar"];
4 -> {5}; 4 -> {5};
} }
subgraph test_1 { subgraph baz {
6 [shape=box label="Enter function test_1"]; 6 [shape=box label="Enter function baz"];
7 [shape=box label="Enter block"]; 7 [shape=box label="Exit function baz"];
8 [shape=box label="Enter when"];
9 [shape=box label="Enter when branch condition "];
10 [shape=box label="Enter &&"];
11 [shape=box label="Access variable R|<local>/x|"];
12 [shape=box label="Type operator: x is B"];
13 [shape=box label="Access variable R|<local>/x|"];
14 [shape=box label="Type operator: x is C"];
15 [shape=box label="Exit &&"];
16 [shape=box label="Exit when branch condition"];
17 [shape=box label="Enter block"];
18 [shape=box label="Access variable R|<local>/x|"];
19 [shape=box label="Function call: R|<local>/x|.R|/A.foo|()"];
20 [shape=box label="Access variable R|<local>/x|"];
21 [shape=box label="Function call: R|<local>/x|.R|/B.bar|()"];
22 [shape=box label="Access variable R|<local>/x|"];
23 [shape=box label="Function call: R|<local>/x|.R|/C.baz|()"];
24 [shape=box label="Exit block"];
25 [shape=box label="Exit when branch result"];
26 [shape=box label="Enter when branch condition else"];
27 [shape=box label="Exit when branch condition"];
28 [shape=box label="Enter block"];
29 [shape=box label="Exit block"];
30 [shape=box label="Exit when branch result"];
31 [shape=box label="Exit when"];
32 [shape=box label="Exit block"];
33 [shape=box label="Exit function test_1"];
6 -> {7}; 6 -> {7};
7 -> {8}; }
subgraph test_1 {
8 [shape=box label="Enter function test_1"];
9 [shape=box label="Enter block"];
10 [shape=box label="Enter when"];
11 [shape=box label="Enter when branch condition "];
12 [shape=box label="Enter &&"];
13 [shape=box label="Access variable R|<local>/x|"];
14 [shape=box label="Type operator: x is B"];
15 [shape=box label="Exit left part of &&"];
16 [shape=box label="Access variable R|<local>/x|"];
17 [shape=box label="Type operator: x is C"];
18 [shape=box label="Exit &&"];
19 [shape=box label="Exit when branch condition"];
20 [shape=box label="Enter block"];
21 [shape=box label="Access variable R|<local>/x|"];
22 [shape=box label="Function call: R|<local>/x|.R|/A.foo|()"];
23 [shape=box label="Access variable R|<local>/x|"];
24 [shape=box label="Function call: R|<local>/x|.R|/B.bar|()"];
25 [shape=box label="Access variable R|<local>/x|"];
26 [shape=box label="Function call: R|<local>/x|.R|/C.baz|()"];
27 [shape=box label="Exit block"];
28 [shape=box label="Exit when branch result"];
29 [shape=box label="Enter when branch condition else"];
30 [shape=box label="Exit when branch condition"];
31 [shape=box label="Enter block"];
32 [shape=box label="Exit block"];
33 [shape=box label="Exit when branch result"];
34 [shape=box label="Exit when"];
35 [shape=box label="Exit block"];
36 [shape=box label="Exit function test_1"];
8 -> {9}; 8 -> {9};
9 -> {10}; 9 -> {10};
10 -> {11}; 10 -> {11};
11 -> {12}; 11 -> {12};
12 -> {15 13}; 12 -> {13};
13 -> {14}; 13 -> {14};
14 -> {15}; 14 -> {18 15};
15 -> {16}; 15 -> {16};
16 -> {17 26}; 16 -> {17};
17 -> {18}; 17 -> {18};
18 -> {19}; 18 -> {19};
19 -> {20}; 19 -> {20 29};
20 -> {21}; 20 -> {21};
21 -> {22}; 21 -> {22};
22 -> {23}; 22 -> {23};
23 -> {24}; 23 -> {24};
24 -> {25}; 24 -> {25};
25 -> {31}; 25 -> {26};
26 -> {27}; 26 -> {27};
27 -> {28}; 27 -> {28};
28 -> {29}; 28 -> {34};
29 -> {30}; 29 -> {30};
30 -> {31}; 30 -> {31};
31 -> {32}; 31 -> {32};
32 -> {33}; 32 -> {33};
33 -> {34};
34 -> {35};
35 -> {36};
} }
subgraph test_2 { subgraph test_2 {
34 [shape=box label="Enter function test_2"]; 37 [shape=box label="Enter function test_2"];
35 [shape=box label="Enter block"]; 38 [shape=box label="Enter block"];
36 [shape=box label="Enter when"]; 39 [shape=box label="Enter when"];
37 [shape=box label="Enter when branch condition "]; 40 [shape=box label="Enter when branch condition "];
38 [shape=box label="Enter ||"]; 41 [shape=box label="Enter ||"];
39 [shape=box label="Access variable R|<local>/x|"];
40 [shape=box label="Type operator: x is B"];
41 [shape=box label="Exit left part of ||"];
42 [shape=box label="Access variable R|<local>/x|"]; 42 [shape=box label="Access variable R|<local>/x|"];
43 [shape=box label="Type operator: x is C"]; 43 [shape=box label="Type operator: x is B"];
44 [shape=box label="Exit ||"]; 44 [shape=box label="Exit left part of ||"];
45 [shape=box label="Exit when branch condition"]; 45 [shape=box label="Access variable R|<local>/x|"];
46 [shape=box label="Enter block"]; 46 [shape=box label="Type operator: x is C"];
47 [shape=box label="Access variable R|<local>/x|"]; 47 [shape=box label="Exit ||"];
48 [shape=box label="Function call: R|<local>/x|.R|/A.foo|()"]; 48 [shape=box label="Exit when branch condition"];
49 [shape=box label="Access variable R|<local>/x|"]; 49 [shape=box label="Enter block"];
50 [shape=box label="Function call: R|<local>/x|.<Unresolved name: bar>#()"]; 50 [shape=box label="Access variable R|<local>/x|"];
51 [shape=box label="Access variable R|<local>/x|"]; 51 [shape=box label="Function call: R|<local>/x|.R|/A.foo|()"];
52 [shape=box label="Function call: R|<local>/x|.<Unresolved name: baz>#()"]; 52 [shape=box label="Access variable R|<local>/x|"];
53 [shape=box label="Exit block"]; 53 [shape=box label="Function call: R|<local>/x|.<Unresolved name: bar>#()"];
54 [shape=box label="Exit when branch result"]; 54 [shape=box label="Access variable R|<local>/x|"];
55 [shape=box label="Enter when branch condition else"]; 55 [shape=box label="Function call: R|<local>/x|.<Unresolved name: baz>#()"];
56 [shape=box label="Exit when branch condition"]; 56 [shape=box label="Exit block"];
57 [shape=box label="Enter block"]; 57 [shape=box label="Exit when branch result"];
58 [shape=box label="Exit block"]; 58 [shape=box label="Enter when branch condition else"];
59 [shape=box label="Exit when branch result"]; 59 [shape=box label="Exit when branch condition"];
60 [shape=box label="Exit when"]; 60 [shape=box label="Enter block"];
61 [shape=box label="Exit block"]; 61 [shape=box label="Exit block"];
62 [shape=box label="Exit function test_2"]; 62 [shape=box label="Exit when branch result"];
63 [shape=box label="Exit when"];
64 [shape=box label="Exit block"];
65 [shape=box label="Exit function test_2"];
34 -> {35};
35 -> {36};
36 -> {37};
37 -> {38}; 37 -> {38};
38 -> {39}; 38 -> {39};
39 -> {40}; 39 -> {40};
40 -> {44 41}; 40 -> {41};
41 -> {42}; 41 -> {42};
42 -> {43}; 42 -> {43};
43 -> {44}; 43 -> {47 44};
44 -> {45}; 44 -> {45};
45 -> {46 55}; 45 -> {46};
46 -> {47}; 46 -> {47};
47 -> {48}; 47 -> {48};
48 -> {49}; 48 -> {49 58};
49 -> {50}; 49 -> {50};
50 -> {51}; 50 -> {51};
51 -> {52}; 51 -> {52};
52 -> {53}; 52 -> {53};
53 -> {54}; 53 -> {54};
54 -> {60}; 54 -> {55};
55 -> {56}; 55 -> {56};
56 -> {57}; 56 -> {57};
57 -> {58}; 57 -> {63};
58 -> {59}; 58 -> {59};
59 -> {60}; 59 -> {60};
60 -> {61}; 60 -> {61};
61 -> {62}; 61 -> {62};
62 -> {63};
63 -> {64};
64 -> {65};
} }
subgraph test_3 { subgraph test_3 {
63 [shape=box label="Enter function test_3"]; 66 [shape=box label="Enter function test_3"];
64 [shape=box label="Enter block"]; 67 [shape=box label="Enter block"];
65 [shape=box label="Enter when"]; 68 [shape=box label="Enter when"];
66 [shape=box label="Enter when branch condition "]; 69 [shape=box label="Enter when branch condition "];
67 [shape=box label="Access variable R|<local>/x|"]; 70 [shape=box label="Access variable R|<local>/x|"];
68 [shape=box label="Type operator: x !is A"]; 71 [shape=box label="Type operator: x !is A"];
69 [shape=box label="Function call: (R|<local>/x| !is R|A|).R|kotlin/Boolean.not|()"]; 72 [shape=box label="Function call: (R|<local>/x| !is R|A|).R|kotlin/Boolean.not|()"];
70 [shape=box label="Exit when branch condition"]; 73 [shape=box label="Exit when branch condition"];
71 [shape=box label="Enter block"]; 74 [shape=box label="Enter block"];
72 [shape=box label="Access variable R|<local>/x|"]; 75 [shape=box label="Access variable R|<local>/x|"];
73 [shape=box label="Function call: R|<local>/x|.R|/A.foo|()"]; 76 [shape=box label="Function call: R|<local>/x|.R|/A.foo|()"];
74 [shape=box label="Exit block"]; 77 [shape=box label="Exit block"];
75 [shape=box label="Exit when branch result"]; 78 [shape=box label="Exit when branch result"];
76 [shape=box label="Enter when branch condition else"]; 79 [shape=box label="Enter when branch condition else"];
77 [shape=box label="Exit when branch condition"]; 80 [shape=box label="Exit when branch condition"];
78 [shape=box label="Enter block"]; 81 [shape=box label="Enter block"];
79 [shape=box label="Exit block"];
80 [shape=box label="Exit when branch result"];
81 [shape=box label="Exit when"];
82 [shape=box label="Exit block"]; 82 [shape=box label="Exit block"];
83 [shape=box label="Exit function test_3"]; 83 [shape=box label="Exit when branch result"];
84 [shape=box label="Exit when"];
85 [shape=box label="Exit block"];
86 [shape=box label="Exit function test_3"];
63 -> {64};
64 -> {65};
65 -> {66};
66 -> {67}; 66 -> {67};
67 -> {68}; 67 -> {68};
68 -> {69}; 68 -> {69};
69 -> {70}; 69 -> {70};
70 -> {71 76}; 70 -> {71};
71 -> {72}; 71 -> {72};
72 -> {73}; 72 -> {73};
73 -> {74}; 73 -> {74 79};
74 -> {75}; 74 -> {75};
75 -> {81}; 75 -> {76};
76 -> {77}; 76 -> {77};
77 -> {78}; 77 -> {78};
78 -> {79}; 78 -> {84};
79 -> {80}; 79 -> {80};
80 -> {81}; 80 -> {81};
81 -> {82}; 81 -> {82};
82 -> {83}; 82 -> {83};
83 -> {84};
84 -> {85};
85 -> {86};
} }
subgraph test_4 { subgraph test_4 {
84 [shape=box label="Enter function test_4"]; 87 [shape=box label="Enter function test_4"];
85 [shape=box label="Enter block"]; 88 [shape=box label="Enter block"];
86 [shape=box label="Enter when"]; 89 [shape=box label="Enter when"];
87 [shape=box label="Enter when branch condition "]; 90 [shape=box label="Enter when branch condition "];
88 [shape=box label="Enter ||"]; 91 [shape=box label="Enter ||"];
89 [shape=box label="Access variable R|<local>/x|"];
90 [shape=box label="Type operator: x !is String"];
91 [shape=box label="Exit left part of ||"];
92 [shape=box label="Access variable R|<local>/x|"]; 92 [shape=box label="Access variable R|<local>/x|"];
93 [shape=box label="Access variable R|kotlin/String.length|"]; 93 [shape=box label="Type operator: x !is String"];
94 [shape=box label="Const: Int(0)"]; 94 [shape=box label="Exit left part of ||"];
95 [shape=box label="Operator =="]; 95 [shape=box label="Access variable R|<local>/x|"];
96 [shape=box label="Exit ||"]; 96 [shape=box label="Access variable R|kotlin/String.length|"];
97 [shape=box label="Exit when branch condition"]; 97 [shape=box label="Const: Int(0)"];
98 [shape=box label="Enter block"]; 98 [shape=box label="Operator =="];
99 [shape=box label="Access variable R|<local>/x|"]; 99 [shape=box label="Exit ||"];
100 [shape=box label="Access variable <Unresolved name: length>#"]; 100 [shape=box label="Exit when branch condition"];
101 [shape=box label="Exit block"]; 101 [shape=box label="Enter block"];
102 [shape=box label="Exit when branch result"]; 102 [shape=box label="Access variable R|<local>/x|"];
103 [shape=box label="Enter when branch condition else"]; 103 [shape=box label="Access variable <Unresolved name: length>#"];
104 [shape=box label="Exit when branch condition"]; 104 [shape=box label="Exit block"];
105 [shape=box label="Enter block"]; 105 [shape=box label="Exit when branch result"];
106 [shape=box label="Exit block"]; 106 [shape=box label="Enter when branch condition else"];
107 [shape=box label="Exit when branch result"]; 107 [shape=box label="Exit when branch condition"];
108 [shape=box label="Exit when"]; 108 [shape=box label="Enter block"];
109 [shape=box label="Access variable R|<local>/x|"]; 109 [shape=box label="Exit block"];
110 [shape=box label="Access variable <Unresolved name: length>#"]; 110 [shape=box label="Exit when branch result"];
111 [shape=box label="Exit block"]; 111 [shape=box label="Exit when"];
112 [shape=box label="Exit function test_4"]; 112 [shape=box label="Access variable R|<local>/x|"];
113 [shape=box label="Access variable <Unresolved name: length>#"];
114 [shape=box label="Exit block"];
115 [shape=box label="Exit function test_4"];
84 -> {85};
85 -> {86};
86 -> {87};
87 -> {88}; 87 -> {88};
88 -> {89}; 88 -> {89};
89 -> {90}; 89 -> {90};
90 -> {96 91}; 90 -> {91};
91 -> {92}; 91 -> {92};
92 -> {93}; 92 -> {93};
93 -> {94}; 93 -> {99 94};
94 -> {95}; 94 -> {95};
95 -> {96}; 95 -> {96};
96 -> {97}; 96 -> {97};
97 -> {98 103}; 97 -> {98};
98 -> {99}; 98 -> {99};
99 -> {100}; 99 -> {100};
100 -> {101}; 100 -> {101 106};
101 -> {102}; 101 -> {102};
102 -> {108}; 102 -> {103};
103 -> {104}; 103 -> {104};
104 -> {105}; 104 -> {105};
105 -> {106}; 105 -> {111};
106 -> {107}; 106 -> {107};
107 -> {108}; 107 -> {108};
108 -> {109}; 108 -> {109};
109 -> {110}; 109 -> {110};
110 -> {111}; 110 -> {111};
111 -> {112}; 111 -> {112};
112 -> {113};
113 -> {114};
114 -> {115};
} }
subgraph test_5 { subgraph test_5 {
113 [shape=box label="Enter function test_5"]; 116 [shape=box label="Enter function test_5"];
114 [shape=box label="Enter block"]; 117 [shape=box label="Enter block"];
115 [shape=box label="Enter when"]; 118 [shape=box label="Enter when"];
116 [shape=box label="Enter when branch condition "]; 119 [shape=box label="Enter when branch condition "];
117 [shape=box label="Enter ||"]; 120 [shape=box label="Enter ||"];
118 [shape=box label="Access variable R|<local>/x|"]; 121 [shape=box label="Access variable R|<local>/x|"];
119 [shape=box label="Const: Null(null)"]; 122 [shape=box label="Const: Null(null)"];
120 [shape=box label="Operator !="]; 123 [shape=box label="Operator !="];
121 [shape=box label="Exit left part of ||"]; 124 [shape=box label="Exit left part of ||"];
122 [shape=box label="Const: Boolean(false)"]; 125 [shape=box label="Const: Boolean(false)"];
123 [shape=box label="Exit ||"]; 126 [shape=box label="Exit ||"];
124 [shape=box label="Exit when branch condition"]; 127 [shape=box label="Exit when branch condition"];
125 [shape=box label="Enter block"]; 128 [shape=box label="Enter block"];
126 [shape=box label="Access variable R|<local>/x|"]; 129 [shape=box label="Access variable R|<local>/x|"];
127 [shape=box label="Function call: R|<local>/x|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()"]; 130 [shape=box label="Function call: R|<local>/x|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()"];
128 [shape=box label="Exit block"]; 131 [shape=box label="Exit block"];
129 [shape=box label="Exit when branch result"]; 132 [shape=box label="Exit when branch result"];
130 [shape=box label="Enter when branch condition else"]; 133 [shape=box label="Enter when branch condition else"];
131 [shape=box label="Exit when branch condition"]; 134 [shape=box label="Exit when branch condition"];
132 [shape=box label="Enter block"]; 135 [shape=box label="Enter block"];
133 [shape=box label="Exit block"];
134 [shape=box label="Exit when branch result"];
135 [shape=box label="Exit when"];
136 [shape=box label="Exit block"]; 136 [shape=box label="Exit block"];
137 [shape=box label="Exit function test_5"]; 137 [shape=box label="Exit when branch result"];
138 [shape=box label="Exit when"];
139 [shape=box label="Exit block"];
140 [shape=box label="Exit function test_5"];
113 -> {114};
114 -> {115};
115 -> {116};
116 -> {117}; 116 -> {117};
117 -> {118}; 117 -> {118};
118 -> {119}; 118 -> {119};
119 -> {120}; 119 -> {120};
120 -> {123 121}; 120 -> {121};
121 -> {122}; 121 -> {122};
122 -> {123}; 122 -> {123};
123 -> {124}; 123 -> {126 124};
124 -> {125 130}; 124 -> {125};
125 -> {126}; 125 -> {126};
126 -> {127}; 126 -> {127};
127 -> {128}; 127 -> {128 133};
128 -> {129}; 128 -> {129};
129 -> {135}; 129 -> {130};
130 -> {131}; 130 -> {131};
131 -> {132}; 131 -> {132};
132 -> {133}; 132 -> {138};
133 -> {134}; 133 -> {134};
134 -> {135}; 134 -> {135};
135 -> {136}; 135 -> {136};
136 -> {137}; 136 -> {137};
137 -> {138};
138 -> {139};
139 -> {140};
} }
subgraph test_6 { subgraph test_6 {
138 [shape=box label="Enter function test_6"]; 141 [shape=box label="Enter function test_6"];
139 [shape=box label="Enter block"]; 142 [shape=box label="Enter block"];
140 [shape=box label="Enter when"]; 143 [shape=box label="Enter when"];
141 [shape=box label="Enter when branch condition "]; 144 [shape=box label="Enter when branch condition "];
142 [shape=box label="Enter ||"]; 145 [shape=box label="Enter ||"];
143 [shape=box label="Const: Boolean(false)"]; 146 [shape=box label="Const: Boolean(false)"];
144 [shape=box label="Exit left part of ||"]; 147 [shape=box label="Exit left part of ||"];
145 [shape=box label="Access variable R|<local>/x|"]; 148 [shape=box label="Access variable R|<local>/x|"];
146 [shape=box label="Const: Null(null)"]; 149 [shape=box label="Const: Null(null)"];
147 [shape=box label="Operator !="]; 150 [shape=box label="Operator !="];
148 [shape=box label="Stub[DEAD]"]; 151 [shape=box label="Stub[DEAD]"];
149 [shape=box label="Exit ||"]; 152 [shape=box label="Exit ||"];
150 [shape=box label="Exit when branch condition"]; 153 [shape=box label="Exit when branch condition"];
151 [shape=box label="Enter block"]; 154 [shape=box label="Enter block"];
152 [shape=box label="Access variable R|<local>/x|"]; 155 [shape=box label="Access variable R|<local>/x|"];
153 [shape=box label="Function call: R|<local>/x|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()"]; 156 [shape=box label="Function call: R|<local>/x|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()"];
154 [shape=box label="Exit block"]; 157 [shape=box label="Exit block"];
155 [shape=box label="Exit when branch result"]; 158 [shape=box label="Exit when branch result"];
156 [shape=box label="Enter when branch condition else"]; 159 [shape=box label="Enter when branch condition else"];
157 [shape=box label="Exit when branch condition"]; 160 [shape=box label="Exit when branch condition"];
158 [shape=box label="Enter block"]; 161 [shape=box label="Enter block"];
159 [shape=box label="Exit block"];
160 [shape=box label="Exit when branch result"];
161 [shape=box label="Exit when"];
162 [shape=box label="Exit block"]; 162 [shape=box label="Exit block"];
163 [shape=box label="Exit function test_6"]; 163 [shape=box label="Exit when branch result"];
164 [shape=box label="Exit when"];
165 [shape=box label="Exit block"];
166 [shape=box label="Exit function test_6"];
138 -> {139};
139 -> {140};
140 -> {141};
141 -> {142}; 141 -> {142};
142 -> {143}; 142 -> {143};
143 -> {144}; 143 -> {144};
143 -> {148} [style=dotted];
144 -> {145}; 144 -> {145};
145 -> {146}; 145 -> {146};
146 -> {147}; 146 -> {147};
147 -> {149}; 146 -> {151} [style=dotted];
148 -> {149} [style=dotted]; 147 -> {148};
148 -> {149};
149 -> {150}; 149 -> {150};
150 -> {151 156}; 150 -> {152};
151 -> {152}; 151 -> {152} [style=dotted];
152 -> {153}; 152 -> {153};
153 -> {154}; 153 -> {154 159};
154 -> {155}; 154 -> {155};
155 -> {161}; 155 -> {156};
156 -> {157}; 156 -> {157};
157 -> {158}; 157 -> {158};
158 -> {159}; 158 -> {164};
159 -> {160}; 159 -> {160};
160 -> {161}; 160 -> {161};
161 -> {162}; 161 -> {162};
162 -> {163}; 162 -> {163};
163 -> {164};
164 -> {165};
165 -> {166};
}
subgraph test_7 {
167 [shape=box label="Enter function test_7"];
168 [shape=box label="Enter block"];
169 [shape=box label="Enter when"];
170 [shape=box label="Enter when branch condition "];
171 [shape=box label="Enter &&"];
172 [shape=box label="Access variable R|<local>/x|"];
173 [shape=box label="Type operator: x is A"];
174 [shape=box label="Exit left part of &&"];
175 [shape=box label="Access variable R|<local>/x|"];
176 [shape=box label="Function call: R|<local>/x|.R|/A.bool|()"];
177 [shape=box label="Exit &&"];
178 [shape=box label="Exit when branch condition"];
179 [shape=box label="Enter block"];
180 [shape=box label="Access variable R|<local>/x|"];
181 [shape=box label="Function call: R|<local>/x|.R|/A.foo|()"];
182 [shape=box label="Exit block"];
183 [shape=box label="Exit when branch result"];
184 [shape=box label="Enter when branch condition else"];
185 [shape=box label="Exit when branch condition"];
186 [shape=box label="Enter block"];
187 [shape=box label="Exit block"];
188 [shape=box label="Exit when branch result"];
189 [shape=box label="Exit when"];
190 [shape=box label="Exit block"];
191 [shape=box label="Exit function test_7"];
167 -> {168};
168 -> {169};
169 -> {170};
170 -> {171};
171 -> {172};
172 -> {173};
173 -> {177 174};
174 -> {175};
175 -> {176};
176 -> {177};
177 -> {178};
178 -> {179 184};
179 -> {180};
180 -> {181};
181 -> {182};
182 -> {183};
183 -> {189};
184 -> {185};
185 -> {186};
186 -> {187};
187 -> {188};
188 -> {189};
189 -> {190};
190 -> {191};
} }
} }
@@ -1,5 +1,7 @@
interface A { interface A {
fun foo() fun foo()
fun bool(): Boolean
} }
interface B : A { interface B : A {
@@ -50,3 +52,9 @@ fun test_6(x: A?) {
x.foo() x.foo()
} }
} }
fun test_7(x: Any) {
if (x is A && x.bool()) {
x.foo()
}
}
@@ -2,6 +2,8 @@ FILE: booleanOperators.kt
public abstract interface A : R|kotlin/Any| { public abstract interface A : R|kotlin/Any| {
public abstract fun foo(): R|kotlin/Unit| public abstract fun foo(): R|kotlin/Unit|
public abstract fun bool(): R|kotlin/Boolean|
} }
public abstract interface B : R|A| { public abstract interface B : R|A| {
public abstract fun bar(): R|kotlin/Unit| public abstract fun bar(): R|kotlin/Unit|
@@ -76,3 +78,13 @@ FILE: booleanOperators.kt
} }
} }
public final fun test_7(x: R|kotlin/Any|): R|kotlin/Unit| {
when () {
(R|<local>/x| is R|A|) && R|<local>/x|.R|/A.bool|() -> {
R|<local>/x|.R|/A.foo|()
}
else -> {
}
}
}
+143 -139
View File
@@ -74,87 +74,89 @@ subgraph test_3 {
33 [shape=box label="Enter when branch condition "]; 33 [shape=box label="Enter when branch condition "];
34 [shape=box label="Enter &&"]; 34 [shape=box label="Enter &&"];
35 [shape=box label="Access variable R|<local>/b|"]; 35 [shape=box label="Access variable R|<local>/b|"];
36 [shape=box label="Access variable R|<local>/x|"]; 36 [shape=box label="Exit left part of &&"];
37 [shape=box label="Type operator: x as Boolean"]; 37 [shape=box label="Access variable R|<local>/x|"];
38 [shape=box label="Exit &&"]; 38 [shape=box label="Type operator: x as Boolean"];
39 [shape=box label="Exit when branch condition"]; 39 [shape=box label="Exit &&"];
40 [shape=box label="Enter block"]; 40 [shape=box label="Exit when branch condition"];
41 [shape=box label="Access variable R|<local>/x|"]; 41 [shape=box label="Enter block"];
42 [shape=box label="Function call: R|<local>/x|.R|kotlin/Boolean.not|()"]; 42 [shape=box label="Access variable R|<local>/x|"];
43 [shape=box label="Exit block"]; 43 [shape=box label="Function call: R|<local>/x|.R|kotlin/Boolean.not|()"];
44 [shape=box label="Exit when branch result"]; 44 [shape=box label="Exit block"];
45 [shape=box label="Enter when branch condition else"]; 45 [shape=box label="Exit when branch result"];
46 [shape=box label="Exit when branch condition"]; 46 [shape=box label="Enter when branch condition else"];
47 [shape=box label="Enter block"]; 47 [shape=box label="Exit when branch condition"];
48 [shape=box label="Exit block"]; 48 [shape=box label="Enter block"];
49 [shape=box label="Exit when branch result"]; 49 [shape=box label="Exit block"];
50 [shape=box label="Exit when"]; 50 [shape=box label="Exit when branch result"];
51 [shape=box label="Access variable R|<local>/x|"]; 51 [shape=box label="Exit when"];
52 [shape=box label="Function call: R|<local>/x|.<Unresolved name: not>#()"]; 52 [shape=box label="Access variable R|<local>/x|"];
53 [shape=box label="Enter when"]; 53 [shape=box label="Function call: R|<local>/x|.<Unresolved name: not>#()"];
54 [shape=box label="Enter when branch condition "]; 54 [shape=box label="Enter when"];
55 [shape=box label="Enter &&"]; 55 [shape=box label="Enter when branch condition "];
56 [shape=box label="Access variable R|<local>/b|"]; 56 [shape=box label="Enter &&"];
57 [shape=box label="Access variable R|<local>/x|"]; 57 [shape=box label="Access variable R|<local>/b|"];
58 [shape=box label="Type operator: x as Boolean"]; 58 [shape=box label="Exit left part of &&"];
59 [shape=box label="Const: Boolean(true)"]; 59 [shape=box label="Access variable R|<local>/x|"];
60 [shape=box label="Operator =="]; 60 [shape=box label="Type operator: x as Boolean"];
61 [shape=box label="Exit &&"]; 61 [shape=box label="Const: Boolean(true)"];
62 [shape=box label="Exit when branch condition"]; 62 [shape=box label="Operator =="];
63 [shape=box label="Enter block"]; 63 [shape=box label="Exit &&"];
64 [shape=box label="Access variable R|<local>/x|"]; 64 [shape=box label="Exit when branch condition"];
65 [shape=box label="Function call: R|<local>/x|.R|kotlin/Boolean.not|()"]; 65 [shape=box label="Enter block"];
66 [shape=box label="Exit block"]; 66 [shape=box label="Access variable R|<local>/x|"];
67 [shape=box label="Exit when branch result"]; 67 [shape=box label="Function call: R|<local>/x|.R|kotlin/Boolean.not|()"];
68 [shape=box label="Enter when branch condition else"]; 68 [shape=box label="Exit block"];
69 [shape=box label="Exit when branch condition"]; 69 [shape=box label="Exit when branch result"];
70 [shape=box label="Enter block"]; 70 [shape=box label="Enter when branch condition else"];
71 [shape=box label="Exit block"]; 71 [shape=box label="Exit when branch condition"];
72 [shape=box label="Exit when branch result"]; 72 [shape=box label="Enter block"];
73 [shape=box label="Exit when"]; 73 [shape=box label="Exit block"];
74 [shape=box label="Access variable R|<local>/x|"]; 74 [shape=box label="Exit when branch result"];
75 [shape=box label="Function call: R|<local>/x|.<Unresolved name: not>#()"]; 75 [shape=box label="Exit when"];
76 [shape=box label="Enter when"]; 76 [shape=box label="Access variable R|<local>/x|"];
77 [shape=box label="Enter when branch condition "]; 77 [shape=box label="Function call: R|<local>/x|.<Unresolved name: not>#()"];
78 [shape=box label="Enter ||"]; 78 [shape=box label="Enter when"];
79 [shape=box label="Access variable R|<local>/b|"]; 79 [shape=box label="Enter when branch condition "];
80 [shape=box label="Exit left part of ||"]; 80 [shape=box label="Enter ||"];
81 [shape=box label="Access variable R|<local>/x|"]; 81 [shape=box label="Access variable R|<local>/b|"];
82 [shape=box label="Type operator: x as Boolean"]; 82 [shape=box label="Exit left part of ||"];
83 [shape=box label="Exit ||"]; 83 [shape=box label="Access variable R|<local>/x|"];
84 [shape=box label="Exit when branch condition"]; 84 [shape=box label="Type operator: x as Boolean"];
85 [shape=box label="Enter block"]; 85 [shape=box label="Exit ||"];
86 [shape=box label="Access variable R|<local>/x|"]; 86 [shape=box label="Exit when branch condition"];
87 [shape=box label="Function call: R|<local>/x|.<Unresolved name: not>#()"]; 87 [shape=box label="Enter block"];
88 [shape=box label="Exit block"]; 88 [shape=box label="Access variable R|<local>/x|"];
89 [shape=box label="Exit when branch result"]; 89 [shape=box label="Function call: R|<local>/x|.<Unresolved name: not>#()"];
90 [shape=box label="Enter when branch condition else"]; 90 [shape=box label="Exit block"];
91 [shape=box label="Exit when branch condition"]; 91 [shape=box label="Exit when branch result"];
92 [shape=box label="Enter block"]; 92 [shape=box label="Enter when branch condition else"];
93 [shape=box label="Exit block"]; 93 [shape=box label="Exit when branch condition"];
94 [shape=box label="Exit when branch result"]; 94 [shape=box label="Enter block"];
95 [shape=box label="Exit when"]; 95 [shape=box label="Exit block"];
96 [shape=box label="Access variable R|<local>/x|"]; 96 [shape=box label="Exit when branch result"];
97 [shape=box label="Function call: R|<local>/x|.<Unresolved name: not>#()"]; 97 [shape=box label="Exit when"];
98 [shape=box label="Exit block"]; 98 [shape=box label="Access variable R|<local>/x|"];
99 [shape=box label="Exit function test_3"]; 99 [shape=box label="Function call: R|<local>/x|.<Unresolved name: not>#()"];
100 [shape=box label="Exit block"];
101 [shape=box label="Exit function test_3"];
30 -> {31}; 30 -> {31};
31 -> {32}; 31 -> {32};
32 -> {33}; 32 -> {33};
33 -> {34}; 33 -> {34};
34 -> {35}; 34 -> {35};
35 -> {38 36}; 35 -> {39 36};
36 -> {37}; 36 -> {37};
37 -> {38}; 37 -> {38};
38 -> {39}; 38 -> {39};
39 -> {40 45}; 39 -> {40};
40 -> {41}; 40 -> {41 46};
41 -> {42}; 41 -> {42};
42 -> {43}; 42 -> {43};
43 -> {44}; 43 -> {44};
44 -> {50}; 44 -> {45};
45 -> {46}; 45 -> {51};
46 -> {47}; 46 -> {47};
47 -> {48}; 47 -> {48};
48 -> {49}; 48 -> {49};
@@ -165,20 +167,20 @@ subgraph test_3 {
53 -> {54}; 53 -> {54};
54 -> {55}; 54 -> {55};
55 -> {56}; 55 -> {56};
56 -> {61 57}; 56 -> {57};
57 -> {58}; 57 -> {63 58};
58 -> {59}; 58 -> {59};
59 -> {60}; 59 -> {60};
60 -> {61}; 60 -> {61};
61 -> {62}; 61 -> {62};
62 -> {63 68}; 62 -> {63};
63 -> {64}; 63 -> {64};
64 -> {65}; 64 -> {65 70};
65 -> {66}; 65 -> {66};
66 -> {67}; 66 -> {67};
67 -> {73}; 67 -> {68};
68 -> {69}; 68 -> {69};
69 -> {70}; 69 -> {75};
70 -> {71}; 70 -> {71};
71 -> {72}; 71 -> {72};
72 -> {73}; 72 -> {73};
@@ -188,19 +190,19 @@ subgraph test_3 {
76 -> {77}; 76 -> {77};
77 -> {78}; 77 -> {78};
78 -> {79}; 78 -> {79};
79 -> {83 80}; 79 -> {80};
80 -> {81}; 80 -> {81};
81 -> {82}; 81 -> {85 82};
82 -> {83}; 82 -> {83};
83 -> {84}; 83 -> {84};
84 -> {85 90}; 84 -> {85};
85 -> {86}; 85 -> {86};
86 -> {87}; 86 -> {87 92};
87 -> {88}; 87 -> {88};
88 -> {89}; 88 -> {89};
89 -> {95}; 89 -> {90};
90 -> {91}; 90 -> {91};
91 -> {92}; 91 -> {97};
92 -> {93}; 92 -> {93};
93 -> {94}; 93 -> {94};
94 -> {95}; 94 -> {95};
@@ -208,74 +210,74 @@ subgraph test_3 {
96 -> {97}; 96 -> {97};
97 -> {98}; 97 -> {98};
98 -> {99}; 98 -> {99};
99 -> {100};
100 -> {101};
} }
subgraph test_4 { subgraph test_4 {
100 [shape=box label="Enter function test_4"]; 102 [shape=box label="Enter function test_4"];
101 [shape=box label="Enter block"]; 103 [shape=box label="Enter block"];
102 [shape=box label="Enter when"]; 104 [shape=box label="Enter when"];
103 [shape=box label="Enter when branch condition "]; 105 [shape=box label="Enter when branch condition "];
104 [shape=box label="Access variable R|<local>/b|"]; 106 [shape=box label="Access variable R|<local>/b|"];
105 [shape=box label="Type operator: b as? Boolean"]; 107 [shape=box label="Type operator: b as? Boolean"];
106 [shape=box label="Const: Null(null)"]; 108 [shape=box label="Const: Null(null)"];
107 [shape=box label="Operator !="]; 109 [shape=box label="Operator !="];
108 [shape=box label="Exit when branch condition"]; 110 [shape=box label="Exit when branch condition"];
109 [shape=box label="Enter block"]; 111 [shape=box label="Enter block"];
110 [shape=box label="Access variable R|<local>/b|"]; 112 [shape=box label="Access variable R|<local>/b|"];
111 [shape=box label="Function call: R|<local>/b|.R|kotlin/Boolean.not|()"]; 113 [shape=box label="Function call: R|<local>/b|.R|kotlin/Boolean.not|()"];
112 [shape=box label="Exit block"]; 114 [shape=box label="Exit block"];
113 [shape=box label="Exit when branch result"]; 115 [shape=box label="Exit when branch result"];
114 [shape=box label="Enter when branch condition else"]; 116 [shape=box label="Enter when branch condition else"];
115 [shape=box label="Exit when branch condition"]; 117 [shape=box label="Exit when branch condition"];
116 [shape=box label="Enter block"]; 118 [shape=box label="Enter block"];
117 [shape=box label="Access variable R|<local>/b|"]; 119 [shape=box label="Access variable R|<local>/b|"];
118 [shape=box label="Function call: R|<local>/b|.<Unresolved name: not>#()"]; 120 [shape=box label="Function call: R|<local>/b|.<Unresolved name: not>#()"];
119 [shape=box label="Exit block"]; 121 [shape=box label="Exit block"];
120 [shape=box label="Exit when branch result"]; 122 [shape=box label="Exit when branch result"];
121 [shape=box label="Exit when"]; 123 [shape=box label="Exit when"];
122 [shape=box label="Access variable R|<local>/b|"]; 124 [shape=box label="Access variable R|<local>/b|"];
123 [shape=box label="Function call: R|<local>/b|.<Unresolved name: not>#()"]; 125 [shape=box label="Function call: R|<local>/b|.<Unresolved name: not>#()"];
124 [shape=box label="Enter when"]; 126 [shape=box label="Enter when"];
125 [shape=box label="Enter when branch condition "]; 127 [shape=box label="Enter when branch condition "];
126 [shape=box label="Access variable R|<local>/b|"]; 128 [shape=box label="Access variable R|<local>/b|"];
127 [shape=box label="Type operator: b as? Boolean"]; 129 [shape=box label="Type operator: b as? Boolean"];
128 [shape=box label="Const: Null(null)"]; 130 [shape=box label="Const: Null(null)"];
129 [shape=box label="Operator =="]; 131 [shape=box label="Operator =="];
130 [shape=box label="Exit when branch condition"]; 132 [shape=box label="Exit when branch condition"];
131 [shape=box label="Enter block"]; 133 [shape=box label="Enter block"];
132 [shape=box label="Access variable R|<local>/b|"]; 134 [shape=box label="Access variable R|<local>/b|"];
133 [shape=box label="Function call: R|<local>/b|.<Unresolved name: not>#()"]; 135 [shape=box label="Function call: R|<local>/b|.<Unresolved name: not>#()"];
134 [shape=box label="Exit block"]; 136 [shape=box label="Exit block"];
135 [shape=box label="Exit when branch result"]; 137 [shape=box label="Exit when branch result"];
136 [shape=box label="Enter when branch condition else"]; 138 [shape=box label="Enter when branch condition else"];
137 [shape=box label="Exit when branch condition"]; 139 [shape=box label="Exit when branch condition"];
138 [shape=box label="Enter block"]; 140 [shape=box label="Enter block"];
139 [shape=box label="Access variable R|<local>/b|"]; 141 [shape=box label="Access variable R|<local>/b|"];
140 [shape=box label="Function call: R|<local>/b|.R|kotlin/Boolean.not|()"]; 142 [shape=box label="Function call: R|<local>/b|.R|kotlin/Boolean.not|()"];
141 [shape=box label="Exit block"]; 143 [shape=box label="Exit block"];
142 [shape=box label="Exit when branch result"]; 144 [shape=box label="Exit when branch result"];
143 [shape=box label="Exit when"]; 145 [shape=box label="Exit when"];
144 [shape=box label="Access variable R|<local>/b|"]; 146 [shape=box label="Access variable R|<local>/b|"];
145 [shape=box label="Function call: R|<local>/b|.<Unresolved name: not>#()"]; 147 [shape=box label="Function call: R|<local>/b|.<Unresolved name: not>#()"];
146 [shape=box label="Exit block"]; 148 [shape=box label="Exit block"];
147 [shape=box label="Exit function test_4"]; 149 [shape=box label="Exit function test_4"];
100 -> {101};
101 -> {102};
102 -> {103}; 102 -> {103};
103 -> {104}; 103 -> {104};
104 -> {105}; 104 -> {105};
105 -> {106}; 105 -> {106};
106 -> {107}; 106 -> {107};
107 -> {108}; 107 -> {108};
108 -> {109 114}; 108 -> {109};
109 -> {110}; 109 -> {110};
110 -> {111}; 110 -> {111 116};
111 -> {112}; 111 -> {112};
112 -> {113}; 112 -> {113};
113 -> {121}; 113 -> {114};
114 -> {115}; 114 -> {115};
115 -> {116}; 115 -> {123};
116 -> {117}; 116 -> {117};
117 -> {118}; 117 -> {118};
118 -> {119}; 118 -> {119};
@@ -290,14 +292,14 @@ subgraph test_4 {
127 -> {128}; 127 -> {128};
128 -> {129}; 128 -> {129};
129 -> {130}; 129 -> {130};
130 -> {131 136}; 130 -> {131};
131 -> {132}; 131 -> {132};
132 -> {133}; 132 -> {133 138};
133 -> {134}; 133 -> {134};
134 -> {135}; 134 -> {135};
135 -> {143}; 135 -> {136};
136 -> {137}; 136 -> {137};
137 -> {138}; 137 -> {145};
138 -> {139}; 138 -> {139};
139 -> {140}; 139 -> {140};
140 -> {141}; 140 -> {141};
@@ -307,6 +309,8 @@ subgraph test_4 {
144 -> {145}; 144 -> {145};
145 -> {146}; 145 -> {146};
146 -> {147}; 146 -> {147};
147 -> {148};
148 -> {149};
} }
} }