[FIR-TEST] Move analysis tests to separate module

This commit is contained in:
Dmitriy Novozhilov
2020-03-18 15:10:46 +03:00
parent 3a479d5d16
commit cc07ae96b3
1477 changed files with 1001 additions and 980 deletions
@@ -0,0 +1,357 @@
digraph bangbang_kt {
graph [nodesep=3]
node [shape=box penwidth=2]
edge [penwidth=2]
subgraph cluster_0 {
color=red
0 [label="Enter function foo" style="filled" fillcolor=red];
1 [label="Exit function foo" style="filled" fillcolor=red];
}
0 -> {1};
subgraph cluster_1 {
color=red
2 [label="Enter function test_0" style="filled" fillcolor=red];
3 [label="Access variable R|<local>/a|"];
4 [label="Check not null: R|<local>/a|!!"];
5 [label="Function call: R|<local>/a|!!.R|/A.foo|()"];
6 [label="Access variable R|<local>/a|"];
7 [label="Function call: R|<local>/a|.R|/A.foo|()"];
8 [label="Exit function test_0" style="filled" fillcolor=red];
}
2 -> {3};
3 -> {4};
4 -> {5};
5 -> {6};
6 -> {7};
7 -> {8};
subgraph cluster_2 {
color=red
9 [label="Enter function test_1" style="filled" fillcolor=red];
subgraph cluster_3 {
color=blue
10 [label="Enter when"];
subgraph cluster_4 {
color=blue
11 [label="Enter when branch condition "];
12 [label="Access variable R|<local>/a|"];
13 [label="Check not null: R|<local>/a|!!"];
14 [label="Function call: R|<local>/a|!!.R|/A.foo|()"];
15 [label="Exit when branch condition"];
}
16 [label="Synthetic else branch"];
17 [label="Enter when branch result"];
subgraph cluster_5 {
color=blue
18 [label="Enter block"];
19 [label="Access variable R|<local>/a|"];
20 [label="Function call: R|<local>/a|.R|/A.foo|()"];
21 [label="Exit block"];
}
22 [label="Exit when branch result"];
23 [label="Exit when"];
}
24 [label="Access variable R|<local>/a|"];
25 [label="Function call: R|<local>/a|.R|/A.foo|()"];
26 [label="Exit function test_1" style="filled" fillcolor=red];
}
9 -> {10};
10 -> {11};
11 -> {12};
12 -> {13};
13 -> {14};
14 -> {15};
15 -> {17 16};
16 -> {23};
17 -> {18};
18 -> {19};
19 -> {20};
20 -> {21};
21 -> {22};
22 -> {23};
23 -> {24};
24 -> {25};
25 -> {26};
subgraph cluster_6 {
color=red
27 [label="Enter function test_2" style="filled" fillcolor=red];
subgraph cluster_7 {
color=blue
28 [label="Enter when"];
subgraph cluster_8 {
color=blue
29 [label="Enter when branch condition "];
subgraph cluster_9 {
color=blue
30 [label="Enter &&"];
31 [label="Access variable R|<local>/a|"];
32 [label="Check not null: R|<local>/a|!!"];
33 [label="Function call: R|<local>/a|!!.R|/A.foo|()"];
34 [label="Exit left part of &&"];
35 [label="Enter right part of &&"];
36 [label="Access variable R|<local>/b|"];
37 [label="Exit &&"];
}
38 [label="Exit when branch condition"];
}
39 [label="Synthetic else branch"];
40 [label="Enter when branch result"];
subgraph cluster_10 {
color=blue
41 [label="Enter block"];
42 [label="Access variable R|<local>/a|"];
43 [label="Function call: R|<local>/a|.R|/A.foo|()"];
44 [label="Exit block"];
}
45 [label="Exit when branch result"];
46 [label="Exit when"];
}
47 [label="Access variable R|<local>/a|"];
48 [label="Function call: R|<local>/a|.R|/A.foo|()"];
49 [label="Exit function test_2" style="filled" fillcolor=red];
}
27 -> {28};
28 -> {29};
29 -> {30};
30 -> {31};
31 -> {32};
32 -> {33};
33 -> {34};
34 -> {37 35};
35 -> {36};
36 -> {37};
37 -> {38};
38 -> {40 39};
39 -> {46};
40 -> {41};
41 -> {42};
42 -> {43};
43 -> {44};
44 -> {45};
45 -> {46};
46 -> {47};
47 -> {48};
48 -> {49};
subgraph cluster_11 {
color=red
50 [label="Enter function test_3" style="filled" fillcolor=red];
subgraph cluster_12 {
color=blue
51 [label="Enter when"];
subgraph cluster_13 {
color=blue
52 [label="Enter when branch condition "];
subgraph cluster_14 {
color=blue
53 [label="Enter &&"];
54 [label="Access variable R|<local>/b|"];
55 [label="Exit left part of &&"];
56 [label="Enter right part of &&"];
57 [label="Access variable R|<local>/a|"];
58 [label="Check not null: R|<local>/a|!!"];
59 [label="Function call: R|<local>/a|!!.R|/A.foo|()"];
60 [label="Exit &&"];
}
61 [label="Exit when branch condition"];
}
62 [label="Synthetic else branch"];
63 [label="Enter when branch result"];
subgraph cluster_15 {
color=blue
64 [label="Enter block"];
65 [label="Access variable R|<local>/a|"];
66 [label="Function call: R|<local>/a|.R|/A.foo|()"];
67 [label="Exit block"];
}
68 [label="Exit when branch result"];
69 [label="Exit when"];
}
70 [label="Access variable R|<local>/a|"];
71 [label="Function call: R|<local>/a|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()"];
72 [label="Exit function test_3" style="filled" fillcolor=red];
}
50 -> {51};
51 -> {52};
52 -> {53};
53 -> {54};
54 -> {55};
55 -> {60 56};
56 -> {57};
57 -> {58};
58 -> {59};
59 -> {60};
60 -> {61};
61 -> {63 62};
62 -> {69};
63 -> {64};
64 -> {65};
65 -> {66};
66 -> {67};
67 -> {68};
68 -> {69};
69 -> {70};
70 -> {71};
71 -> {72};
subgraph cluster_16 {
color=red
73 [label="Enter function test_4" style="filled" fillcolor=red];
subgraph cluster_17 {
color=blue
74 [label="Enter when"];
subgraph cluster_18 {
color=blue
75 [label="Enter when branch condition "];
subgraph cluster_19 {
color=blue
76 [label="Enter ||"];
77 [label="Access variable R|<local>/a|"];
78 [label="Check not null: R|<local>/a|!!"];
79 [label="Function call: R|<local>/a|!!.R|/A.foo|()"];
80 [label="Exit left part of ||"];
81 [label="Enter right part of ||"];
82 [label="Access variable R|<local>/b|"];
83 [label="Exit ||"];
}
84 [label="Exit when branch condition"];
}
85 [label="Synthetic else branch"];
86 [label="Enter when branch result"];
subgraph cluster_20 {
color=blue
87 [label="Enter block"];
88 [label="Access variable R|<local>/a|"];
89 [label="Function call: R|<local>/a|.R|/A.foo|()"];
90 [label="Exit block"];
}
91 [label="Exit when branch result"];
92 [label="Exit when"];
}
93 [label="Access variable R|<local>/a|"];
94 [label="Function call: R|<local>/a|.R|/A.foo|()"];
95 [label="Exit function test_4" style="filled" fillcolor=red];
}
73 -> {74};
74 -> {75};
75 -> {76};
76 -> {77};
77 -> {78};
78 -> {79};
79 -> {80};
80 -> {83 81};
81 -> {82};
82 -> {83};
83 -> {84};
84 -> {86 85};
85 -> {92};
86 -> {87};
87 -> {88};
88 -> {89};
89 -> {90};
90 -> {91};
91 -> {92};
92 -> {93};
93 -> {94};
94 -> {95};
subgraph cluster_21 {
color=red
96 [label="Enter function test_5" style="filled" fillcolor=red];
subgraph cluster_22 {
color=blue
97 [label="Enter when"];
subgraph cluster_23 {
color=blue
98 [label="Enter when branch condition "];
subgraph cluster_24 {
color=blue
99 [label="Enter ||"];
100 [label="Access variable R|<local>/b|"];
101 [label="Exit left part of ||"];
102 [label="Enter right part of ||"];
103 [label="Access variable R|<local>/a|"];
104 [label="Check not null: R|<local>/a|!!"];
105 [label="Function call: R|<local>/a|!!.R|/A.foo|()"];
106 [label="Exit ||"];
}
107 [label="Exit when branch condition"];
}
108 [label="Synthetic else branch"];
109 [label="Enter when branch result"];
subgraph cluster_25 {
color=blue
110 [label="Enter block"];
111 [label="Access variable R|<local>/a|"];
112 [label="Function call: R|<local>/a|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()"];
113 [label="Exit block"];
}
114 [label="Exit when branch result"];
115 [label="Exit when"];
}
116 [label="Access variable R|<local>/a|"];
117 [label="Function call: R|<local>/a|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()"];
118 [label="Exit function test_5" style="filled" fillcolor=red];
}
96 -> {97};
97 -> {98};
98 -> {99};
99 -> {100};
100 -> {101};
101 -> {106 102};
102 -> {103};
103 -> {104};
104 -> {105};
105 -> {106};
106 -> {107};
107 -> {109 108};
108 -> {115};
109 -> {110};
110 -> {111};
111 -> {112};
112 -> {113};
113 -> {114};
114 -> {115};
115 -> {116};
116 -> {117};
117 -> {118};
subgraph cluster_26 {
color=red
119 [label="Enter function test_6" style="filled" fillcolor=red];
120 [label="Access variable R|<local>/x|"];
121 [label="Check not null: R|<local>/x|!!"];
122 [label="Function call: R|<local>/x|!!.R|/A.foo|()"];
123 [label="Exit function test_6" style="filled" fillcolor=red];
}
119 -> {120};
120 -> {121};
121 -> {122};
122 -> {123};
subgraph cluster_27 {
color=red
124 [label="Enter function test_7" style="filled" fillcolor=red];
125 [label="Access variable R|<local>/x|"];
126 [label="Check not null: R|<local>/x|!!"];
127 [label="Function call: R|<local>/x|!!.R|/A.foo|()"];
128 [label="Exit function test_7" style="filled" fillcolor=red];
}
124 -> {125};
125 -> {126};
126 -> {127};
127 -> {128};
}
@@ -0,0 +1,52 @@
// !DUMP_CFG
interface A {
fun foo(): Boolean
}
fun test_0(a: A?) {
a!!.foo()
a.foo()
}
fun test_1(a: A?) {
if (a!!.foo()) {
a.foo()
}
a.foo()
}
fun test_2(a: A?, b: Boolean) {
if (a!!.foo() && b) {
a.foo()
}
a.foo()
}
fun test_3(a: A?, b: Boolean) {
if (b && a!!.foo()) {
a.foo() // OK
}
a.<!INAPPLICABLE_CANDIDATE!>foo<!>() // Bad
}
fun test_4(a: A?, b: Boolean) {
if (a!!.foo() || b) {
a.foo()
}
a.foo()
}
fun test_5(a: A?, b: Boolean) {
if (b || a!!.foo()) {
a.<!INAPPLICABLE_CANDIDATE!>foo<!>()
}
a.<!INAPPLICABLE_CANDIDATE!>foo<!>()
}
fun <X : A?> test_6(x: X) {
x!!.foo()
}
fun <X : A> test_7(x: X?) {
x!!.foo()
}
@@ -0,0 +1,60 @@
FILE: bangbang.kt
public abstract interface A : R|kotlin/Any| {
public abstract fun foo(): R|kotlin/Boolean|
}
public final fun test_0(a: R|A?|): R|kotlin/Unit| {
R|<local>/a|!!.R|/A.foo|()
R|<local>/a|.R|/A.foo|()
}
public final fun test_1(a: R|A?|): R|kotlin/Unit| {
when () {
R|<local>/a|!!.R|/A.foo|() -> {
R|<local>/a|.R|/A.foo|()
}
}
R|<local>/a|.R|/A.foo|()
}
public final fun test_2(a: R|A?|, b: R|kotlin/Boolean|): R|kotlin/Unit| {
when () {
R|<local>/a|!!.R|/A.foo|() && R|<local>/b| -> {
R|<local>/a|.R|/A.foo|()
}
}
R|<local>/a|.R|/A.foo|()
}
public final fun test_3(a: R|A?|, b: R|kotlin/Boolean|): R|kotlin/Unit| {
when () {
R|<local>/b| && R|<local>/a|!!.R|/A.foo|() -> {
R|<local>/a|.R|/A.foo|()
}
}
R|<local>/a|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()
}
public final fun test_4(a: R|A?|, b: R|kotlin/Boolean|): R|kotlin/Unit| {
when () {
R|<local>/a|!!.R|/A.foo|() || R|<local>/b| -> {
R|<local>/a|.R|/A.foo|()
}
}
R|<local>/a|.R|/A.foo|()
}
public final fun test_5(a: R|A?|, b: R|kotlin/Boolean|): R|kotlin/Unit| {
when () {
R|<local>/b| || R|<local>/a|!!.R|/A.foo|() -> {
R|<local>/a|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()
}
}
R|<local>/a|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()
}
public final fun <X : R|A?|> test_6(x: R|X|): R|kotlin/Unit| {
R|<local>/x|!!.R|/A.foo|()
}
public final fun <X : R|A|> test_7(x: R|X?|): R|kotlin/Unit| {
R|<local>/x|!!.R|/A.foo|()
}
@@ -0,0 +1,836 @@
digraph booleanOperators_kt {
graph [nodesep=3]
node [shape=box penwidth=2]
edge [penwidth=2]
subgraph cluster_0 {
color=red
0 [label="Enter function foo" style="filled" fillcolor=red];
1 [label="Exit function foo" style="filled" fillcolor=red];
}
0 -> {1};
subgraph cluster_1 {
color=red
2 [label="Enter function bool" style="filled" fillcolor=red];
3 [label="Exit function bool" style="filled" fillcolor=red];
}
2 -> {3};
subgraph cluster_2 {
color=red
4 [label="Enter function bar" style="filled" fillcolor=red];
5 [label="Exit function bar" style="filled" fillcolor=red];
}
4 -> {5};
subgraph cluster_3 {
color=red
6 [label="Enter function baz" style="filled" fillcolor=red];
7 [label="Exit function baz" style="filled" fillcolor=red];
}
6 -> {7};
subgraph cluster_4 {
color=red
8 [label="Enter function test_1" style="filled" fillcolor=red];
subgraph cluster_5 {
color=blue
9 [label="Enter when"];
subgraph cluster_6 {
color=blue
10 [label="Enter when branch condition "];
subgraph cluster_7 {
color=blue
11 [label="Enter &&"];
12 [label="Access variable R|<local>/x|"];
13 [label="Type operator: (R|<local>/x| is R|B|)"];
14 [label="Exit left part of &&"];
15 [label="Enter right part of &&"];
16 [label="Access variable R|<local>/x|"];
17 [label="Type operator: (R|<local>/x| is R|C|)"];
18 [label="Exit &&"];
}
19 [label="Exit when branch condition"];
}
20 [label="Synthetic else branch"];
21 [label="Enter when branch result"];
subgraph cluster_8 {
color=blue
22 [label="Enter block"];
23 [label="Access variable R|<local>/x|"];
24 [label="Function call: R|<local>/x|.R|/A.foo|()"];
25 [label="Access variable R|<local>/x|"];
26 [label="Function call: R|<local>/x|.R|/B.bar|()"];
27 [label="Access variable R|<local>/x|"];
28 [label="Function call: R|<local>/x|.R|/C.baz|()"];
29 [label="Exit block"];
}
30 [label="Exit when branch result"];
31 [label="Exit when"];
}
32 [label="Exit function test_1" style="filled" fillcolor=red];
}
8 -> {9};
9 -> {10};
10 -> {11};
11 -> {12};
12 -> {13};
13 -> {14};
14 -> {18 15};
15 -> {16};
16 -> {17};
17 -> {18};
18 -> {19};
19 -> {21 20};
20 -> {31};
21 -> {22};
22 -> {23};
23 -> {24};
24 -> {25};
25 -> {26};
26 -> {27};
27 -> {28};
28 -> {29};
29 -> {30};
30 -> {31};
31 -> {32};
subgraph cluster_9 {
color=red
33 [label="Enter function test_2" style="filled" fillcolor=red];
subgraph cluster_10 {
color=blue
34 [label="Enter when"];
subgraph cluster_11 {
color=blue
35 [label="Enter when branch condition "];
subgraph cluster_12 {
color=blue
36 [label="Enter ||"];
37 [label="Access variable R|<local>/x|"];
38 [label="Type operator: (R|<local>/x| is R|B|)"];
39 [label="Exit left part of ||"];
40 [label="Enter right part of ||"];
41 [label="Access variable R|<local>/x|"];
42 [label="Type operator: (R|<local>/x| is R|C|)"];
43 [label="Exit ||"];
}
44 [label="Exit when branch condition"];
}
45 [label="Synthetic else branch"];
46 [label="Enter when branch result"];
subgraph cluster_13 {
color=blue
47 [label="Enter block"];
48 [label="Access variable R|<local>/x|"];
49 [label="Function call: R|<local>/x|.R|/A.foo|()"];
50 [label="Access variable R|<local>/x|"];
51 [label="Function call: R|<local>/x|.<Unresolved name: bar>#()"];
52 [label="Access variable R|<local>/x|"];
53 [label="Function call: R|<local>/x|.<Unresolved name: baz>#()"];
54 [label="Exit block"];
}
55 [label="Exit when branch result"];
56 [label="Exit when"];
}
57 [label="Exit function test_2" style="filled" fillcolor=red];
}
33 -> {34};
34 -> {35};
35 -> {36};
36 -> {37};
37 -> {38};
38 -> {39};
39 -> {43 40};
40 -> {41};
41 -> {42};
42 -> {43};
43 -> {44};
44 -> {46 45};
45 -> {56};
46 -> {47};
47 -> {48};
48 -> {49};
49 -> {50};
50 -> {51};
51 -> {52};
52 -> {53};
53 -> {54};
54 -> {55};
55 -> {56};
56 -> {57};
subgraph cluster_14 {
color=red
58 [label="Enter function test_3" style="filled" fillcolor=red];
subgraph cluster_15 {
color=blue
59 [label="Enter when"];
subgraph cluster_16 {
color=blue
60 [label="Enter when branch condition "];
61 [label="Access variable R|<local>/x|"];
62 [label="Type operator: (R|<local>/x| !is R|A|)"];
63 [label="Function call: (R|<local>/x| !is R|A|).R|kotlin/Boolean.not|()"];
64 [label="Exit when branch condition"];
}
65 [label="Synthetic else branch"];
66 [label="Enter when branch result"];
subgraph cluster_17 {
color=blue
67 [label="Enter block"];
68 [label="Access variable R|<local>/x|"];
69 [label="Function call: R|<local>/x|.R|/A.foo|()"];
70 [label="Exit block"];
}
71 [label="Exit when branch result"];
72 [label="Exit when"];
}
73 [label="Exit function test_3" style="filled" fillcolor=red];
}
58 -> {59};
59 -> {60};
60 -> {61};
61 -> {62};
62 -> {63};
63 -> {64};
64 -> {66 65};
65 -> {72};
66 -> {67};
67 -> {68};
68 -> {69};
69 -> {70};
70 -> {71};
71 -> {72};
72 -> {73};
subgraph cluster_18 {
color=red
74 [label="Enter function test_4" style="filled" fillcolor=red];
subgraph cluster_19 {
color=blue
75 [label="Enter when"];
subgraph cluster_20 {
color=blue
76 [label="Enter when branch condition "];
subgraph cluster_21 {
color=blue
77 [label="Enter ||"];
78 [label="Access variable R|<local>/x|"];
79 [label="Type operator: (R|<local>/x| !is R|kotlin/String|)"];
80 [label="Exit left part of ||"];
81 [label="Enter right part of ||"];
82 [label="Access variable R|<local>/x|"];
83 [label="Access variable R|kotlin/String.length|"];
84 [label="Const: Int(0)"];
85 [label="Operator =="];
86 [label="Exit ||"];
}
87 [label="Exit when branch condition"];
}
88 [label="Synthetic else branch"];
89 [label="Enter when branch result"];
subgraph cluster_22 {
color=blue
90 [label="Enter block"];
91 [label="Access variable R|<local>/x|"];
92 [label="Access variable <Unresolved name: length>#"];
93 [label="Exit block"];
}
94 [label="Exit when branch result"];
95 [label="Exit when"];
}
96 [label="Access variable R|<local>/x|"];
97 [label="Access variable <Unresolved name: length>#"];
98 [label="Exit function test_4" style="filled" fillcolor=red];
}
74 -> {75};
75 -> {76};
76 -> {77};
77 -> {78};
78 -> {79};
79 -> {80};
80 -> {86 81};
81 -> {82};
82 -> {83};
83 -> {84};
84 -> {85};
85 -> {86};
86 -> {87};
87 -> {89 88};
88 -> {95};
89 -> {90};
90 -> {91};
91 -> {92};
92 -> {93};
93 -> {94};
94 -> {95};
95 -> {96};
96 -> {97};
97 -> {98};
subgraph cluster_23 {
color=red
99 [label="Enter function test_5" style="filled" fillcolor=red];
subgraph cluster_24 {
color=blue
100 [label="Enter when"];
subgraph cluster_25 {
color=blue
101 [label="Enter when branch condition "];
subgraph cluster_26 {
color=blue
102 [label="Enter &&"];
103 [label="Access variable R|<local>/x|"];
104 [label="Type operator: (R|<local>/x| is R|A|)"];
105 [label="Exit left part of &&"];
106 [label="Enter right part of &&"];
107 [label="Access variable R|<local>/x|"];
108 [label="Function call: R|<local>/x|.R|/A.bool|()"];
109 [label="Exit &&"];
}
110 [label="Exit when branch condition"];
}
111 [label="Synthetic else branch"];
112 [label="Enter when branch result"];
subgraph cluster_27 {
color=blue
113 [label="Enter block"];
114 [label="Access variable R|<local>/x|"];
115 [label="Function call: R|<local>/x|.R|/A.foo|()"];
116 [label="Exit block"];
}
117 [label="Exit when branch result"];
118 [label="Exit when"];
}
119 [label="Exit function test_5" style="filled" fillcolor=red];
}
99 -> {100};
100 -> {101};
101 -> {102};
102 -> {103};
103 -> {104};
104 -> {105};
105 -> {109 106};
106 -> {107};
107 -> {108};
108 -> {109};
109 -> {110};
110 -> {112 111};
111 -> {118};
112 -> {113};
113 -> {114};
114 -> {115};
115 -> {116};
116 -> {117};
117 -> {118};
118 -> {119};
subgraph cluster_28 {
color=red
120 [label="Enter function test_6" style="filled" fillcolor=red];
subgraph cluster_29 {
color=blue
121 [label="Enter when"];
subgraph cluster_30 {
color=blue
122 [label="Enter when branch condition "];
123 [label="Access variable R|<local>/x|"];
124 [label="Type operator: (R|<local>/x| !is R|A|)"];
125 [label="Function call: (R|<local>/x| !is R|A|).R|kotlin/Boolean.not|()"];
126 [label="Exit when branch condition"];
}
127 [label="Synthetic else branch"];
128 [label="Enter when branch result"];
subgraph cluster_31 {
color=blue
129 [label="Enter block"];
130 [label="Access variable R|<local>/x|"];
131 [label="Function call: R|<local>/x|.R|/A.foo|()"];
132 [label="Exit block"];
}
133 [label="Exit when branch result"];
134 [label="Exit when"];
}
135 [label="Exit function test_6" style="filled" fillcolor=red];
}
120 -> {121};
121 -> {122};
122 -> {123};
123 -> {124};
124 -> {125};
125 -> {126};
126 -> {128 127};
127 -> {134};
128 -> {129};
129 -> {130};
130 -> {131};
131 -> {132};
132 -> {133};
133 -> {134};
134 -> {135};
subgraph cluster_32 {
color=red
136 [label="Enter function test_7" style="filled" fillcolor=red];
subgraph cluster_33 {
color=blue
137 [label="Enter when"];
subgraph cluster_34 {
color=blue
138 [label="Enter when branch condition "];
subgraph cluster_35 {
color=blue
139 [label="Enter ||"];
140 [label="Access variable R|<local>/x|"];
141 [label="Type operator: (R|<local>/x| is R|A|)"];
142 [label="Exit left part of ||"];
143 [label="Enter right part of ||"];
144 [label="Const: Boolean(false)"];
145 [label="Exit ||"];
}
146 [label="Exit when branch condition"];
}
147 [label="Synthetic else branch"];
148 [label="Enter when branch result"];
subgraph cluster_36 {
color=blue
149 [label="Enter block"];
150 [label="Access variable R|<local>/x|"];
151 [label="Function call: R|<local>/x|.<Unresolved name: foo>#()"];
152 [label="Exit block"];
}
153 [label="Exit when branch result"];
154 [label="Exit when"];
}
155 [label="Exit function test_7" style="filled" fillcolor=red];
}
136 -> {137};
137 -> {138};
138 -> {139};
139 -> {140};
140 -> {141};
141 -> {142};
142 -> {145 143};
143 -> {144};
144 -> {145};
145 -> {146};
146 -> {148 147};
147 -> {154};
148 -> {149};
149 -> {150};
150 -> {151};
151 -> {152};
152 -> {153};
153 -> {154};
154 -> {155};
subgraph cluster_37 {
color=red
156 [label="Enter function test_8" style="filled" fillcolor=red];
subgraph cluster_38 {
color=blue
157 [label="Enter when"];
subgraph cluster_39 {
color=blue
158 [label="Enter when branch condition "];
subgraph cluster_40 {
color=blue
159 [label="Enter ||"];
160 [label="Const: Boolean(false)"];
161 [label="Exit left part of ||"];
162 [label="Enter right part of ||"];
163 [label="Access variable R|<local>/x|"];
164 [label="Type operator: (R|<local>/x| is R|A|)"];
165 [label="Exit ||"];
}
166 [label="Exit when branch condition"];
}
167 [label="Synthetic else branch"];
168 [label="Enter when branch result"];
subgraph cluster_41 {
color=blue
169 [label="Enter block"];
170 [label="Access variable R|<local>/x|"];
171 [label="Function call: R|<local>/x|.<Unresolved name: foo>#()"];
172 [label="Exit block"];
}
173 [label="Exit when branch result"];
174 [label="Exit when"];
}
175 [label="Exit function test_8" style="filled" fillcolor=red];
}
156 -> {157};
157 -> {158};
158 -> {159};
159 -> {160};
160 -> {161};
161 -> {162};
161 -> {165} [style=dotted];
162 -> {163};
163 -> {164};
164 -> {165};
165 -> {166};
166 -> {168 167};
167 -> {174};
168 -> {169};
169 -> {170};
170 -> {171};
171 -> {172};
172 -> {173};
173 -> {174};
174 -> {175};
subgraph cluster_42 {
color=red
176 [label="Enter function test_9" style="filled" fillcolor=red];
subgraph cluster_43 {
color=blue
177 [label="Enter when"];
subgraph cluster_44 {
color=blue
178 [label="Enter when branch condition "];
subgraph cluster_45 {
color=blue
179 [label="Enter ||"];
180 [label="Access variable R|<local>/x|"];
181 [label="Type operator: (R|<local>/x| is R|A|)"];
182 [label="Exit left part of ||"];
183 [label="Enter right part of ||"];
184 [label="Const: Boolean(true)"];
185 [label="Exit ||"];
}
186 [label="Exit when branch condition"];
}
187 [label="Synthetic else branch"];
188 [label="Enter when branch result"];
subgraph cluster_46 {
color=blue
189 [label="Enter block"];
190 [label="Access variable R|<local>/x|"];
191 [label="Function call: R|<local>/x|.<Unresolved name: foo>#()"];
192 [label="Exit block"];
}
193 [label="Exit when branch result"];
194 [label="Exit when"];
}
195 [label="Exit function test_9" style="filled" fillcolor=red];
}
176 -> {177};
177 -> {178};
178 -> {179};
179 -> {180};
180 -> {181};
181 -> {182};
182 -> {185 183};
183 -> {184};
184 -> {185};
185 -> {186};
186 -> {188 187};
187 -> {194};
188 -> {189};
189 -> {190};
190 -> {191};
191 -> {192};
192 -> {193};
193 -> {194};
194 -> {195};
subgraph cluster_47 {
color=red
196 [label="Enter function test_10" style="filled" fillcolor=red];
subgraph cluster_48 {
color=blue
197 [label="Enter when"];
subgraph cluster_49 {
color=blue
198 [label="Enter when branch condition "];
subgraph cluster_50 {
color=blue
199 [label="Enter ||"];
200 [label="Const: Boolean(true)"];
201 [label="Exit left part of ||"];
202 [label="Enter right part of ||" style="filled" fillcolor=gray];
203 [label="Access variable R|<local>/x|" style="filled" fillcolor=gray];
204 [label="Type operator: (R|<local>/x| is R|A|)" style="filled" fillcolor=gray];
205 [label="Exit ||"];
}
206 [label="Exit when branch condition"];
}
207 [label="Synthetic else branch"];
208 [label="Enter when branch result"];
subgraph cluster_51 {
color=blue
209 [label="Enter block"];
210 [label="Access variable R|<local>/x|"];
211 [label="Function call: R|<local>/x|.<Unresolved name: foo>#()"];
212 [label="Exit block"];
}
213 [label="Exit when branch result"];
214 [label="Exit when"];
}
215 [label="Exit function test_10" style="filled" fillcolor=red];
}
196 -> {197};
197 -> {198};
198 -> {199};
199 -> {200};
200 -> {201};
201 -> {205};
201 -> {202} [style=dotted];
202 -> {203} [style=dotted];
203 -> {204} [style=dotted];
204 -> {205} [style=dotted];
205 -> {206};
206 -> {208 207};
207 -> {214};
208 -> {209};
209 -> {210};
210 -> {211};
211 -> {212};
212 -> {213};
213 -> {214};
214 -> {215};
subgraph cluster_52 {
color=red
216 [label="Enter function test_11" style="filled" fillcolor=red];
subgraph cluster_53 {
color=blue
217 [label="Enter when"];
subgraph cluster_54 {
color=blue
218 [label="Enter when branch condition "];
subgraph cluster_55 {
color=blue
219 [label="Enter &&"];
220 [label="Const: Boolean(false)"];
221 [label="Exit left part of &&"];
222 [label="Enter right part of &&" style="filled" fillcolor=gray];
223 [label="Access variable R|<local>/x|" style="filled" fillcolor=gray];
224 [label="Type operator: (R|<local>/x| is R|A|)" style="filled" fillcolor=gray];
225 [label="Exit &&"];
}
226 [label="Exit when branch condition"];
}
227 [label="Synthetic else branch"];
228 [label="Enter when branch result"];
subgraph cluster_56 {
color=blue
229 [label="Enter block"];
230 [label="Access variable R|<local>/x|"];
231 [label="Function call: R|<local>/x|.<Unresolved name: foo>#()"];
232 [label="Exit block"];
}
233 [label="Exit when branch result"];
234 [label="Exit when"];
}
235 [label="Exit function test_11" style="filled" fillcolor=red];
}
216 -> {217};
217 -> {218};
218 -> {219};
219 -> {220};
220 -> {221};
221 -> {225};
221 -> {222} [style=dotted];
222 -> {223} [style=dotted];
223 -> {224} [style=dotted];
224 -> {225} [style=dotted];
225 -> {226};
226 -> {228 227};
227 -> {234};
228 -> {229};
229 -> {230};
230 -> {231};
231 -> {232};
232 -> {233};
233 -> {234};
234 -> {235};
subgraph cluster_57 {
color=red
236 [label="Enter function test_12" style="filled" fillcolor=red];
subgraph cluster_58 {
color=blue
237 [label="Enter when"];
subgraph cluster_59 {
color=blue
238 [label="Enter when branch condition "];
subgraph cluster_60 {
color=blue
239 [label="Enter &&"];
240 [label="Access variable R|<local>/x|"];
241 [label="Type operator: (R|<local>/x| is R|A|)"];
242 [label="Exit left part of &&"];
243 [label="Enter right part of &&"];
244 [label="Const: Boolean(false)"];
245 [label="Exit &&"];
}
246 [label="Exit when branch condition"];
}
247 [label="Synthetic else branch"];
248 [label="Enter when branch result"];
subgraph cluster_61 {
color=blue
249 [label="Enter block"];
250 [label="Access variable R|<local>/x|"];
251 [label="Function call: R|<local>/x|.R|/A.foo|()"];
252 [label="Exit block"];
}
253 [label="Exit when branch result"];
254 [label="Exit when"];
}
255 [label="Exit function test_12" style="filled" fillcolor=red];
}
236 -> {237};
237 -> {238};
238 -> {239};
239 -> {240};
240 -> {241};
241 -> {242};
242 -> {245 243};
243 -> {244};
244 -> {245};
245 -> {246};
246 -> {248 247};
247 -> {254};
248 -> {249};
249 -> {250};
250 -> {251};
251 -> {252};
252 -> {253};
253 -> {254};
254 -> {255};
subgraph cluster_62 {
color=red
256 [label="Enter function test_13" style="filled" fillcolor=red];
subgraph cluster_63 {
color=blue
257 [label="Enter when"];
subgraph cluster_64 {
color=blue
258 [label="Enter when branch condition "];
subgraph cluster_65 {
color=blue
259 [label="Enter &&"];
260 [label="Const: Boolean(true)"];
261 [label="Exit left part of &&"];
262 [label="Enter right part of &&"];
263 [label="Access variable R|<local>/x|"];
264 [label="Type operator: (R|<local>/x| is R|A|)"];
265 [label="Exit &&"];
}
266 [label="Exit when branch condition"];
}
267 [label="Synthetic else branch"];
268 [label="Enter when branch result"];
subgraph cluster_66 {
color=blue
269 [label="Enter block"];
270 [label="Access variable R|<local>/x|"];
271 [label="Function call: R|<local>/x|.R|/A.foo|()"];
272 [label="Exit block"];
}
273 [label="Exit when branch result"];
274 [label="Exit when"];
}
275 [label="Exit function test_13" style="filled" fillcolor=red];
}
256 -> {257};
257 -> {258};
258 -> {259};
259 -> {260};
260 -> {261};
261 -> {262};
261 -> {265} [style=dotted];
262 -> {263};
263 -> {264};
264 -> {265};
265 -> {266};
266 -> {268 267};
267 -> {274};
268 -> {269};
269 -> {270};
270 -> {271};
271 -> {272};
272 -> {273};
273 -> {274};
274 -> {275};
subgraph cluster_67 {
color=red
276 [label="Enter function test_14" style="filled" fillcolor=red];
subgraph cluster_68 {
color=blue
277 [label="Enter when"];
subgraph cluster_69 {
color=blue
278 [label="Enter when branch condition "];
subgraph cluster_70 {
color=blue
279 [label="Enter &&"];
280 [label="Access variable R|<local>/x|"];
281 [label="Type operator: (R|<local>/x| is R|A|)"];
282 [label="Exit left part of &&"];
283 [label="Enter right part of &&"];
284 [label="Const: Boolean(false)"];
285 [label="Exit &&"];
}
286 [label="Exit when branch condition"];
}
287 [label="Synthetic else branch"];
288 [label="Enter when branch result"];
subgraph cluster_71 {
color=blue
289 [label="Enter block"];
290 [label="Access variable R|<local>/x|"];
291 [label="Function call: R|<local>/x|.R|/A.foo|()"];
292 [label="Exit block"];
}
293 [label="Exit when branch result"];
294 [label="Exit when"];
}
295 [label="Exit function test_14" style="filled" fillcolor=red];
}
276 -> {277};
277 -> {278};
278 -> {279};
279 -> {280};
280 -> {281};
281 -> {282};
282 -> {285 283};
283 -> {284};
284 -> {285};
285 -> {286};
286 -> {288 287};
287 -> {294};
288 -> {289};
289 -> {290};
290 -> {291};
291 -> {292};
292 -> {293};
293 -> {294};
294 -> {295};
}
@@ -0,0 +1,109 @@
// !DUMP_CFG
interface A {
fun foo()
fun bool(): Boolean
}
interface B : A {
fun bar()
}
interface C : A {
fun baz()
}
fun test_1(x: Any) {
if (x is B && x is C) {
x.foo()
x.bar()
x.baz()
}
}
fun test_2(x: Any) {
if (x is B || x is C) {
x.foo()
x.<!UNRESOLVED_REFERENCE!>bar<!>()
x.<!UNRESOLVED_REFERENCE!>baz<!>()
}
}
fun test_3(x: Any) {
if (!(x !is A)) {
x.foo()
}
}
fun test_4(x: Any) {
if (x !is String || x.length == 0) {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
x.<!UNRESOLVED_REFERENCE!>length<!>
}
fun test_5(x: Any) {
if (x is A && x.bool()) {
x.foo()
}
}
fun test_6(x: Any) {
if ((x !is A).not()) {
x.foo()
}
}
// || and const
fun test_7(x: Any) {
if (x is A || false) {
// TODO: should be smartcast
x.<!UNRESOLVED_REFERENCE!>foo<!>()
}
}
fun test_8(x: Any) {
if (false || x is A) {
// TODO: should be smartcast
x.<!UNRESOLVED_REFERENCE!>foo<!>()
}
}
fun test_9(x: Any) {
if (x is A || true) {
x.<!UNRESOLVED_REFERENCE!>foo<!>()
}
}
fun test_10(x: Any) {
if (true || x is A) {
x.<!UNRESOLVED_REFERENCE!>foo<!>()
}
}
// && and const
fun test_11(x: Any, b: Boolean) {
if (false && x is A) {
x.<!UNRESOLVED_REFERENCE!>foo<!>()
}
}
fun test_12(x: Any, b: Boolean) {
if (x is A && false) {
x.foo()
}
}
fun test_13(x: Any, b: Boolean) {
if (true && x is A) {
x.foo()
}
}
fun test_14(x: Any, b: Boolean) {
if (x is A && false) {
x.foo()
}
}
@@ -0,0 +1,132 @@
FILE: booleanOperators.kt
public abstract interface A : R|kotlin/Any| {
public abstract fun foo(): R|kotlin/Unit|
public abstract fun bool(): R|kotlin/Boolean|
}
public abstract interface B : R|A| {
public abstract fun bar(): R|kotlin/Unit|
}
public abstract interface C : R|A| {
public abstract fun baz(): R|kotlin/Unit|
}
public final fun test_1(x: R|kotlin/Any|): R|kotlin/Unit| {
when () {
(R|<local>/x| is R|B|) && (R|<local>/x| is R|C|) -> {
R|<local>/x|.R|/A.foo|()
R|<local>/x|.R|/B.bar|()
R|<local>/x|.R|/C.baz|()
}
}
}
public final fun test_2(x: R|kotlin/Any|): R|kotlin/Unit| {
when () {
(R|<local>/x| is R|B|) || (R|<local>/x| is R|C|) -> {
R|<local>/x|.R|/A.foo|()
R|<local>/x|.<Unresolved name: bar>#()
R|<local>/x|.<Unresolved name: baz>#()
}
}
}
public final fun test_3(x: R|kotlin/Any|): R|kotlin/Unit| {
when () {
(R|<local>/x| !is R|A|).R|kotlin/Boolean.not|() -> {
R|<local>/x|.R|/A.foo|()
}
}
}
public final fun test_4(x: R|kotlin/Any|): R|kotlin/Unit| {
when () {
(R|<local>/x| !is R|kotlin/String|) || ==(R|<local>/x|.R|kotlin/String.length|, Int(0)) -> {
R|<local>/x|.<Unresolved name: length>#
}
}
R|<local>/x|.<Unresolved name: length>#
}
public final fun test_5(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|()
}
}
}
public final fun test_6(x: R|kotlin/Any|): R|kotlin/Unit| {
when () {
(R|<local>/x| !is R|A|).R|kotlin/Boolean.not|() -> {
R|<local>/x|.R|/A.foo|()
}
}
}
public final fun test_7(x: R|kotlin/Any|): R|kotlin/Unit| {
when () {
(R|<local>/x| is R|A|) || Boolean(false) -> {
R|<local>/x|.<Unresolved name: foo>#()
}
}
}
public final fun test_8(x: R|kotlin/Any|): R|kotlin/Unit| {
when () {
Boolean(false) || (R|<local>/x| is R|A|) -> {
R|<local>/x|.<Unresolved name: foo>#()
}
}
}
public final fun test_9(x: R|kotlin/Any|): R|kotlin/Unit| {
when () {
(R|<local>/x| is R|A|) || Boolean(true) -> {
R|<local>/x|.<Unresolved name: foo>#()
}
}
}
public final fun test_10(x: R|kotlin/Any|): R|kotlin/Unit| {
when () {
Boolean(true) || (R|<local>/x| is R|A|) -> {
R|<local>/x|.<Unresolved name: foo>#()
}
}
}
public final fun test_11(x: R|kotlin/Any|, b: R|kotlin/Boolean|): R|kotlin/Unit| {
when () {
Boolean(false) && (R|<local>/x| is R|A|) -> {
R|<local>/x|.<Unresolved name: foo>#()
}
}
}
public final fun test_12(x: R|kotlin/Any|, b: R|kotlin/Boolean|): R|kotlin/Unit| {
when () {
(R|<local>/x| is R|A|) && Boolean(false) -> {
R|<local>/x|.R|/A.foo|()
}
}
}
public final fun test_13(x: R|kotlin/Any|, b: R|kotlin/Boolean|): R|kotlin/Unit| {
when () {
Boolean(true) && (R|<local>/x| is R|A|) -> {
R|<local>/x|.R|/A.foo|()
}
}
}
public final fun test_14(x: R|kotlin/Any|, b: R|kotlin/Boolean|): R|kotlin/Unit| {
when () {
(R|<local>/x| is R|A|) && Boolean(false) -> {
R|<local>/x|.R|/A.foo|()
}
}
}
@@ -0,0 +1,582 @@
digraph equalsToBoolean_kt {
graph [nodesep=3]
node [shape=box penwidth=2]
edge [penwidth=2]
subgraph cluster_0 {
color=red
0 [label="Enter function foo" style="filled" fillcolor=red];
1 [label="Exit function foo" style="filled" fillcolor=red];
}
0 -> {1};
subgraph cluster_1 {
color=red
2 [label="Enter function getter" style="filled" fillcolor=red];
3 [label="Exit function getter" style="filled" fillcolor=red];
}
2 -> {3};
subgraph cluster_2 {
color=red
4 [label="Enter property" style="filled" fillcolor=red];
5 [label="Exit property" style="filled" fillcolor=red];
}
4 -> {5};
subgraph cluster_3 {
color=red
6 [label="Enter function test_1" style="filled" fillcolor=red];
subgraph cluster_4 {
color=blue
7 [label="Enter when"];
subgraph cluster_5 {
color=blue
8 [label="Enter when branch condition "];
9 [label="Access variable R|<local>/b|"];
10 [label="Const: Boolean(true)"];
11 [label="Operator =="];
12 [label="Const: Boolean(true)"];
13 [label="Operator =="];
14 [label="Exit when branch condition"];
}
subgraph cluster_6 {
color=blue
15 [label="Enter when branch condition else"];
16 [label="Exit when branch condition"];
}
17 [label="Enter when branch result"];
subgraph cluster_7 {
color=blue
18 [label="Enter block"];
19 [label="Access variable R|<local>/b|"];
20 [label="Function call: R|<local>/b|.<Inapplicable(WRONG_RECEIVER): [kotlin/Boolean.not]>#()"];
21 [label="Exit block"];
}
22 [label="Exit when branch result"];
23 [label="Enter when branch result"];
subgraph cluster_8 {
color=blue
24 [label="Enter block"];
25 [label="Access variable R|<local>/b|"];
26 [label="Function call: R|<local>/b|.R|kotlin/Boolean.not|()"];
27 [label="Exit block"];
}
28 [label="Exit when branch result"];
29 [label="Exit when"];
}
30 [label="Exit function test_1" style="filled" fillcolor=red];
}
6 -> {7};
7 -> {8};
8 -> {9};
9 -> {10};
10 -> {11};
11 -> {12};
12 -> {13};
13 -> {14};
14 -> {23 15};
15 -> {16};
16 -> {17};
17 -> {18};
18 -> {19};
19 -> {20};
20 -> {21};
21 -> {22};
22 -> {29};
23 -> {24};
24 -> {25};
25 -> {26};
26 -> {27};
27 -> {28};
28 -> {29};
29 -> {30};
subgraph cluster_9 {
color=red
31 [label="Enter function test_2" style="filled" fillcolor=red];
subgraph cluster_10 {
color=blue
32 [label="Enter when"];
subgraph cluster_11 {
color=blue
33 [label="Enter when branch condition "];
34 [label="Access variable R|<local>/b|"];
35 [label="Const: Boolean(true)"];
36 [label="Operator =="];
37 [label="Const: Boolean(true)"];
38 [label="Operator !="];
39 [label="Exit when branch condition"];
}
subgraph cluster_12 {
color=blue
40 [label="Enter when branch condition else"];
41 [label="Exit when branch condition"];
}
42 [label="Enter when branch result"];
subgraph cluster_13 {
color=blue
43 [label="Enter block"];
44 [label="Access variable R|<local>/b|"];
45 [label="Function call: R|<local>/b|.R|kotlin/Boolean.not|()"];
46 [label="Exit block"];
}
47 [label="Exit when branch result"];
48 [label="Enter when branch result"];
subgraph cluster_14 {
color=blue
49 [label="Enter block"];
50 [label="Access variable R|<local>/b|"];
51 [label="Function call: R|<local>/b|.<Inapplicable(WRONG_RECEIVER): [kotlin/Boolean.not]>#()"];
52 [label="Exit block"];
}
53 [label="Exit when branch result"];
54 [label="Exit when"];
}
55 [label="Exit function test_2" style="filled" fillcolor=red];
}
31 -> {32};
32 -> {33};
33 -> {34};
34 -> {35};
35 -> {36};
36 -> {37};
37 -> {38};
38 -> {39};
39 -> {48 40};
40 -> {41};
41 -> {42};
42 -> {43};
43 -> {44};
44 -> {45};
45 -> {46};
46 -> {47};
47 -> {54};
48 -> {49};
49 -> {50};
50 -> {51};
51 -> {52};
52 -> {53};
53 -> {54};
54 -> {55};
subgraph cluster_15 {
color=red
56 [label="Enter function test_3" style="filled" fillcolor=red];
subgraph cluster_16 {
color=blue
57 [label="Enter when"];
subgraph cluster_17 {
color=blue
58 [label="Enter when branch condition "];
59 [label="Access variable R|<local>/b|"];
60 [label="Const: Boolean(true)"];
61 [label="Operator =="];
62 [label="Const: Boolean(false)"];
63 [label="Operator =="];
64 [label="Exit when branch condition"];
}
subgraph cluster_18 {
color=blue
65 [label="Enter when branch condition else"];
66 [label="Exit when branch condition"];
}
67 [label="Enter when branch result"];
subgraph cluster_19 {
color=blue
68 [label="Enter block"];
69 [label="Access variable R|<local>/b|"];
70 [label="Function call: R|<local>/b|.R|kotlin/Boolean.not|()"];
71 [label="Exit block"];
}
72 [label="Exit when branch result"];
73 [label="Enter when branch result"];
subgraph cluster_20 {
color=blue
74 [label="Enter block"];
75 [label="Access variable R|<local>/b|"];
76 [label="Function call: R|<local>/b|.<Inapplicable(WRONG_RECEIVER): [kotlin/Boolean.not]>#()"];
77 [label="Exit block"];
}
78 [label="Exit when branch result"];
79 [label="Exit when"];
}
80 [label="Exit function test_3" style="filled" fillcolor=red];
}
56 -> {57};
57 -> {58};
58 -> {59};
59 -> {60};
60 -> {61};
61 -> {62};
62 -> {63};
63 -> {64};
64 -> {73 65};
65 -> {66};
66 -> {67};
67 -> {68};
68 -> {69};
69 -> {70};
70 -> {71};
71 -> {72};
72 -> {79};
73 -> {74};
74 -> {75};
75 -> {76};
76 -> {77};
77 -> {78};
78 -> {79};
79 -> {80};
subgraph cluster_21 {
color=red
81 [label="Enter function test_4" style="filled" fillcolor=red];
subgraph cluster_22 {
color=blue
82 [label="Enter when"];
subgraph cluster_23 {
color=blue
83 [label="Enter when branch condition "];
84 [label="Access variable R|<local>/b|"];
85 [label="Const: Boolean(true)"];
86 [label="Operator =="];
87 [label="Const: Boolean(false)"];
88 [label="Operator !="];
89 [label="Exit when branch condition"];
}
subgraph cluster_24 {
color=blue
90 [label="Enter when branch condition else"];
91 [label="Exit when branch condition"];
}
92 [label="Enter when branch result"];
subgraph cluster_25 {
color=blue
93 [label="Enter block"];
94 [label="Access variable R|<local>/b|"];
95 [label="Function call: R|<local>/b|.<Inapplicable(WRONG_RECEIVER): [kotlin/Boolean.not]>#()"];
96 [label="Exit block"];
}
97 [label="Exit when branch result"];
98 [label="Enter when branch result"];
subgraph cluster_26 {
color=blue
99 [label="Enter block"];
100 [label="Access variable R|<local>/b|"];
101 [label="Function call: R|<local>/b|.R|kotlin/Boolean.not|()"];
102 [label="Exit block"];
}
103 [label="Exit when branch result"];
104 [label="Exit when"];
}
105 [label="Exit function test_4" style="filled" fillcolor=red];
}
81 -> {82};
82 -> {83};
83 -> {84};
84 -> {85};
85 -> {86};
86 -> {87};
87 -> {88};
88 -> {89};
89 -> {98 90};
90 -> {91};
91 -> {92};
92 -> {93};
93 -> {94};
94 -> {95};
95 -> {96};
96 -> {97};
97 -> {104};
98 -> {99};
99 -> {100};
100 -> {101};
101 -> {102};
102 -> {103};
103 -> {104};
104 -> {105};
subgraph cluster_27 {
color=red
106 [label="Enter function test_5" style="filled" fillcolor=red];
subgraph cluster_28 {
color=blue
107 [label="Enter when"];
subgraph cluster_29 {
color=blue
108 [label="Enter when branch condition "];
109 [label="Access variable R|<local>/b|"];
110 [label="Const: Boolean(true)"];
111 [label="Operator !="];
112 [label="Const: Boolean(true)"];
113 [label="Operator =="];
114 [label="Exit when branch condition"];
}
subgraph cluster_30 {
color=blue
115 [label="Enter when branch condition else"];
116 [label="Exit when branch condition"];
}
117 [label="Enter when branch result"];
subgraph cluster_31 {
color=blue
118 [label="Enter block"];
119 [label="Access variable R|<local>/b|"];
120 [label="Function call: R|<local>/b|.R|kotlin/Boolean.not|()"];
121 [label="Exit block"];
}
122 [label="Exit when branch result"];
123 [label="Enter when branch result"];
subgraph cluster_32 {
color=blue
124 [label="Enter block"];
125 [label="Access variable R|<local>/b|"];
126 [label="Function call: R|<local>/b|.<Inapplicable(WRONG_RECEIVER): [kotlin/Boolean.not]>#()"];
127 [label="Exit block"];
}
128 [label="Exit when branch result"];
129 [label="Exit when"];
}
130 [label="Exit function test_5" style="filled" fillcolor=red];
}
106 -> {107};
107 -> {108};
108 -> {109};
109 -> {110};
110 -> {111};
111 -> {112};
112 -> {113};
113 -> {114};
114 -> {123 115};
115 -> {116};
116 -> {117};
117 -> {118};
118 -> {119};
119 -> {120};
120 -> {121};
121 -> {122};
122 -> {129};
123 -> {124};
124 -> {125};
125 -> {126};
126 -> {127};
127 -> {128};
128 -> {129};
129 -> {130};
subgraph cluster_33 {
color=red
131 [label="Enter function test_6" style="filled" fillcolor=red];
subgraph cluster_34 {
color=blue
132 [label="Enter when"];
subgraph cluster_35 {
color=blue
133 [label="Enter when branch condition "];
134 [label="Access variable R|<local>/b|"];
135 [label="Const: Boolean(true)"];
136 [label="Operator !="];
137 [label="Const: Boolean(true)"];
138 [label="Operator !="];
139 [label="Exit when branch condition"];
}
subgraph cluster_36 {
color=blue
140 [label="Enter when branch condition else"];
141 [label="Exit when branch condition"];
}
142 [label="Enter when branch result"];
subgraph cluster_37 {
color=blue
143 [label="Enter block"];
144 [label="Access variable R|<local>/b|"];
145 [label="Function call: R|<local>/b|.<Inapplicable(WRONG_RECEIVER): [kotlin/Boolean.not]>#()"];
146 [label="Exit block"];
}
147 [label="Exit when branch result"];
148 [label="Enter when branch result"];
subgraph cluster_38 {
color=blue
149 [label="Enter block"];
150 [label="Access variable R|<local>/b|"];
151 [label="Function call: R|<local>/b|.R|kotlin/Boolean.not|()"];
152 [label="Exit block"];
}
153 [label="Exit when branch result"];
154 [label="Exit when"];
}
155 [label="Exit function test_6" style="filled" fillcolor=red];
}
131 -> {132};
132 -> {133};
133 -> {134};
134 -> {135};
135 -> {136};
136 -> {137};
137 -> {138};
138 -> {139};
139 -> {148 140};
140 -> {141};
141 -> {142};
142 -> {143};
143 -> {144};
144 -> {145};
145 -> {146};
146 -> {147};
147 -> {154};
148 -> {149};
149 -> {150};
150 -> {151};
151 -> {152};
152 -> {153};
153 -> {154};
154 -> {155};
subgraph cluster_39 {
color=red
156 [label="Enter function test_7" style="filled" fillcolor=red];
subgraph cluster_40 {
color=blue
157 [label="Enter when"];
subgraph cluster_41 {
color=blue
158 [label="Enter when branch condition "];
159 [label="Access variable R|<local>/b|"];
160 [label="Const: Boolean(true)"];
161 [label="Operator !="];
162 [label="Const: Boolean(false)"];
163 [label="Operator =="];
164 [label="Exit when branch condition"];
}
subgraph cluster_42 {
color=blue
165 [label="Enter when branch condition else"];
166 [label="Exit when branch condition"];
}
167 [label="Enter when branch result"];
subgraph cluster_43 {
color=blue
168 [label="Enter block"];
169 [label="Access variable R|<local>/b|"];
170 [label="Function call: R|<local>/b|.<Inapplicable(WRONG_RECEIVER): [kotlin/Boolean.not]>#()"];
171 [label="Exit block"];
}
172 [label="Exit when branch result"];
173 [label="Enter when branch result"];
subgraph cluster_44 {
color=blue
174 [label="Enter block"];
175 [label="Access variable R|<local>/b|"];
176 [label="Function call: R|<local>/b|.R|kotlin/Boolean.not|()"];
177 [label="Exit block"];
}
178 [label="Exit when branch result"];
179 [label="Exit when"];
}
180 [label="Exit function test_7" style="filled" fillcolor=red];
}
156 -> {157};
157 -> {158};
158 -> {159};
159 -> {160};
160 -> {161};
161 -> {162};
162 -> {163};
163 -> {164};
164 -> {173 165};
165 -> {166};
166 -> {167};
167 -> {168};
168 -> {169};
169 -> {170};
170 -> {171};
171 -> {172};
172 -> {179};
173 -> {174};
174 -> {175};
175 -> {176};
176 -> {177};
177 -> {178};
178 -> {179};
179 -> {180};
subgraph cluster_45 {
color=red
181 [label="Enter function test_8" style="filled" fillcolor=red];
subgraph cluster_46 {
color=blue
182 [label="Enter when"];
subgraph cluster_47 {
color=blue
183 [label="Enter when branch condition "];
184 [label="Access variable R|<local>/b|"];
185 [label="Const: Boolean(true)"];
186 [label="Operator !="];
187 [label="Const: Boolean(false)"];
188 [label="Operator !="];
189 [label="Exit when branch condition"];
}
subgraph cluster_48 {
color=blue
190 [label="Enter when branch condition else"];
191 [label="Exit when branch condition"];
}
192 [label="Enter when branch result"];
subgraph cluster_49 {
color=blue
193 [label="Enter block"];
194 [label="Access variable R|<local>/b|"];
195 [label="Function call: R|<local>/b|.R|kotlin/Boolean.not|()"];
196 [label="Exit block"];
}
197 [label="Exit when branch result"];
198 [label="Enter when branch result"];
subgraph cluster_50 {
color=blue
199 [label="Enter block"];
200 [label="Access variable R|<local>/b|"];
201 [label="Function call: R|<local>/b|.<Inapplicable(WRONG_RECEIVER): [kotlin/Boolean.not]>#()"];
202 [label="Exit block"];
}
203 [label="Exit when branch result"];
204 [label="Exit when"];
}
205 [label="Exit function test_8" style="filled" fillcolor=red];
}
181 -> {182};
182 -> {183};
183 -> {184};
184 -> {185};
185 -> {186};
186 -> {187};
187 -> {188};
188 -> {189};
189 -> {198 190};
190 -> {191};
191 -> {192};
192 -> {193};
193 -> {194};
194 -> {195};
195 -> {196};
196 -> {197};
197 -> {204};
198 -> {199};
199 -> {200};
200 -> {201};
201 -> {202};
202 -> {203};
203 -> {204};
204 -> {205};
}
@@ -0,0 +1,69 @@
// !DUMP_CFG
interface A {
fun foo()
val b: Boolean
}
fun test_1(b: Boolean?) {
if ((b == true) == true) {
b.not() // OK
} else {
b.<!INAPPLICABLE_CANDIDATE!>not<!>() // Bad
}
}
fun test_2(b: Boolean?) {
if ((b == true) != true) {
b.<!INAPPLICABLE_CANDIDATE!>not<!>() // Bad
} else {
b.not() // OK
}
}
fun test_3(b: Boolean?) {
if ((b == true) == false) {
b.<!INAPPLICABLE_CANDIDATE!>not<!>() // Bad
} else {
b.not() // OK
}
}
fun test_4(b: Boolean?) {
if ((b == true) != false) {
b.not() // OK
} else {
b.<!INAPPLICABLE_CANDIDATE!>not<!>() // Bad
}
}
fun test_5(b: Boolean?) {
if ((b != true) == true) {
b.<!INAPPLICABLE_CANDIDATE!>not<!>() // Bad
} else {
b.not() // OK
}
}
fun test_6(b: Boolean?) {
if ((b != true) != true) {
b.not() // OK
} else {
b.<!INAPPLICABLE_CANDIDATE!>not<!>() // Bad
}
}
fun test_7(b: Boolean?) {
if ((b != true) == false) {
b.not() // OK
} else {
b.<!INAPPLICABLE_CANDIDATE!>not<!>() // Bad
}
}
fun test_8(b: Boolean?) {
if ((b != true) != false) {
b.<!INAPPLICABLE_CANDIDATE!>not<!>() // Bad
} else {
b.not() // OK
}
}
@@ -0,0 +1,96 @@
FILE: equalsToBoolean.kt
public abstract interface A : R|kotlin/Any| {
public abstract fun foo(): R|kotlin/Unit|
public abstract val b: R|kotlin/Boolean|
public get(): R|kotlin/Boolean|
}
public final fun test_1(b: R|kotlin/Boolean?|): R|kotlin/Unit| {
when () {
==(==(R|<local>/b|, Boolean(true)), Boolean(true)) -> {
R|<local>/b|.R|kotlin/Boolean.not|()
}
else -> {
R|<local>/b|.<Inapplicable(WRONG_RECEIVER): [kotlin/Boolean.not]>#()
}
}
}
public final fun test_2(b: R|kotlin/Boolean?|): R|kotlin/Unit| {
when () {
!=(==(R|<local>/b|, Boolean(true)), Boolean(true)) -> {
R|<local>/b|.<Inapplicable(WRONG_RECEIVER): [kotlin/Boolean.not]>#()
}
else -> {
R|<local>/b|.R|kotlin/Boolean.not|()
}
}
}
public final fun test_3(b: R|kotlin/Boolean?|): R|kotlin/Unit| {
when () {
==(==(R|<local>/b|, Boolean(true)), Boolean(false)) -> {
R|<local>/b|.<Inapplicable(WRONG_RECEIVER): [kotlin/Boolean.not]>#()
}
else -> {
R|<local>/b|.R|kotlin/Boolean.not|()
}
}
}
public final fun test_4(b: R|kotlin/Boolean?|): R|kotlin/Unit| {
when () {
!=(==(R|<local>/b|, Boolean(true)), Boolean(false)) -> {
R|<local>/b|.R|kotlin/Boolean.not|()
}
else -> {
R|<local>/b|.<Inapplicable(WRONG_RECEIVER): [kotlin/Boolean.not]>#()
}
}
}
public final fun test_5(b: R|kotlin/Boolean?|): R|kotlin/Unit| {
when () {
==(!=(R|<local>/b|, Boolean(true)), Boolean(true)) -> {
R|<local>/b|.<Inapplicable(WRONG_RECEIVER): [kotlin/Boolean.not]>#()
}
else -> {
R|<local>/b|.R|kotlin/Boolean.not|()
}
}
}
public final fun test_6(b: R|kotlin/Boolean?|): R|kotlin/Unit| {
when () {
!=(!=(R|<local>/b|, Boolean(true)), Boolean(true)) -> {
R|<local>/b|.R|kotlin/Boolean.not|()
}
else -> {
R|<local>/b|.<Inapplicable(WRONG_RECEIVER): [kotlin/Boolean.not]>#()
}
}
}
public final fun test_7(b: R|kotlin/Boolean?|): R|kotlin/Unit| {
when () {
==(!=(R|<local>/b|, Boolean(true)), Boolean(false)) -> {
R|<local>/b|.R|kotlin/Boolean.not|()
}
else -> {
R|<local>/b|.<Inapplicable(WRONG_RECEIVER): [kotlin/Boolean.not]>#()
}
}
}
public final fun test_8(b: R|kotlin/Boolean?|): R|kotlin/Unit| {
when () {
!=(!=(R|<local>/b|, Boolean(true)), Boolean(false)) -> {
R|<local>/b|.<Inapplicable(WRONG_RECEIVER): [kotlin/Boolean.not]>#()
}
else -> {
R|<local>/b|.R|kotlin/Boolean.not|()
}
}
}
@@ -0,0 +1,426 @@
digraph jumpFromRhsOfOperator_kt {
graph [nodesep=3]
node [shape=box penwidth=2]
edge [penwidth=2]
subgraph cluster_0 {
color=red
0 [label="Enter function foo" style="filled" fillcolor=red];
1 [label="Exit function foo" style="filled" fillcolor=red];
}
0 -> {1};
subgraph cluster_1 {
color=red
2 [label="Enter function test_1" style="filled" fillcolor=red];
subgraph cluster_2 {
color=blue
3 [label="Enter ||"];
4 [label="Access variable R|<local>/a|"];
5 [label="Const: Null(null)"];
6 [label="Operator !="];
7 [label="Exit left part of ||"];
8 [label="Enter right part of ||"];
9 [label="Function call: R|java/lang/Exception.Exception|()"];
10 [label="Throw: throw R|java/lang/Exception.Exception|()"];
11 [label="Stub" style="filled" fillcolor=gray];
12 [label="Exit ||"];
}
13 [label="Access variable R|<local>/a|"];
14 [label="Function call: R|<local>/a|.R|/A.foo|()"];
15 [label="Exit function test_1" style="filled" fillcolor=red];
}
2 -> {3};
3 -> {4};
4 -> {5};
5 -> {6};
6 -> {7};
7 -> {12 8};
8 -> {9};
9 -> {10};
10 -> {15};
10 -> {11} [style=dotted];
11 -> {12} [style=dotted];
12 -> {13};
13 -> {14};
14 -> {15};
subgraph cluster_3 {
color=red
16 [label="Enter function teat_2" style="filled" fillcolor=red];
subgraph cluster_4 {
color=blue
17 [label="Enter &&"];
18 [label="Access variable R|<local>/a|"];
19 [label="Const: Null(null)"];
20 [label="Operator =="];
21 [label="Exit left part of &&"];
22 [label="Enter right part of &&"];
23 [label="Function call: R|java/lang/Exception.Exception|()"];
24 [label="Throw: throw R|java/lang/Exception.Exception|()"];
25 [label="Stub" style="filled" fillcolor=gray];
26 [label="Exit &&"];
}
27 [label="Access variable R|<local>/a|"];
28 [label="Function call: R|<local>/a|.R|/A.foo|()"];
29 [label="Exit function teat_2" style="filled" fillcolor=red];
}
16 -> {17};
17 -> {18};
18 -> {19};
19 -> {20};
20 -> {21};
21 -> {26 22};
22 -> {23};
23 -> {24};
24 -> {29};
24 -> {25} [style=dotted];
25 -> {26} [style=dotted];
26 -> {27};
27 -> {28};
28 -> {29};
subgraph cluster_5 {
color=red
30 [label="Enter function test_3" style="filled" fillcolor=red];
subgraph cluster_6 {
color=blue
31 [label="Enter when"];
subgraph cluster_7 {
color=blue
32 [label="Enter when branch condition "];
subgraph cluster_8 {
color=blue
33 [label="Enter ||"];
34 [label="Access variable R|<local>/a|"];
35 [label="Const: Null(null)"];
36 [label="Operator !="];
37 [label="Exit left part of ||"];
38 [label="Enter right part of ||"];
39 [label="Function call: R|java/lang/Exception.Exception|()"];
40 [label="Throw: throw R|java/lang/Exception.Exception|()"];
41 [label="Stub" style="filled" fillcolor=gray];
42 [label="Exit ||"];
}
43 [label="Exit when branch condition"];
}
44 [label="Synthetic else branch"];
45 [label="Enter when branch result"];
subgraph cluster_9 {
color=blue
46 [label="Enter block"];
47 [label="Access variable R|<local>/a|"];
48 [label="Function call: R|<local>/a|.R|/A.foo|()"];
49 [label="Exit block"];
}
50 [label="Exit when branch result"];
51 [label="Exit when"];
}
52 [label="Access variable R|<local>/a|"];
53 [label="Function call: R|<local>/a|.R|/A.foo|()"];
54 [label="Exit function test_3" style="filled" fillcolor=red];
}
30 -> {31};
31 -> {32};
32 -> {33};
33 -> {34};
34 -> {35};
35 -> {36};
36 -> {37};
37 -> {42 38};
38 -> {39};
39 -> {40};
40 -> {54};
40 -> {41} [style=dotted];
41 -> {42} [style=dotted];
42 -> {43};
43 -> {45 44};
44 -> {51};
45 -> {46};
46 -> {47};
47 -> {48};
48 -> {49};
49 -> {50};
50 -> {51};
51 -> {52};
52 -> {53};
53 -> {54};
subgraph cluster_10 {
color=red
55 [label="Enter function test_4" style="filled" fillcolor=red];
subgraph cluster_11 {
color=blue
56 [label="Enter when"];
subgraph cluster_12 {
color=blue
57 [label="Enter when branch condition "];
subgraph cluster_13 {
color=blue
58 [label="Enter &&"];
59 [label="Access variable R|<local>/a|"];
60 [label="Const: Null(null)"];
61 [label="Operator =="];
62 [label="Exit left part of &&"];
63 [label="Enter right part of &&"];
64 [label="Function call: R|java/lang/Exception.Exception|()"];
65 [label="Throw: throw R|java/lang/Exception.Exception|()"];
66 [label="Stub" style="filled" fillcolor=gray];
67 [label="Exit &&"];
}
68 [label="Exit when branch condition"];
}
69 [label="Synthetic else branch"];
70 [label="Enter when branch result"];
subgraph cluster_14 {
color=blue
71 [label="Enter block"];
72 [label="Access variable R|<local>/a|"];
73 [label="Function call: R|<local>/a|.R|/A.foo|()"];
74 [label="Exit block"];
}
75 [label="Exit when branch result"];
76 [label="Exit when"];
}
77 [label="Access variable R|<local>/a|"];
78 [label="Function call: R|<local>/a|.R|/A.foo|()"];
79 [label="Exit function test_4" style="filled" fillcolor=red];
}
55 -> {56};
56 -> {57};
57 -> {58};
58 -> {59};
59 -> {60};
60 -> {61};
61 -> {62};
62 -> {67 63};
63 -> {64};
64 -> {65};
65 -> {79};
65 -> {66} [style=dotted];
66 -> {67} [style=dotted];
67 -> {68};
68 -> {70 69};
69 -> {76};
70 -> {71};
71 -> {72};
72 -> {73};
73 -> {74};
74 -> {75};
75 -> {76};
76 -> {77};
77 -> {78};
78 -> {79};
subgraph cluster_15 {
color=red
80 [label="Enter function test_5" style="filled" fillcolor=red];
subgraph cluster_16 {
color=blue
81 [label="Enter ||"];
82 [label="Access variable R|<local>/a|"];
83 [label="Const: Null(null)"];
84 [label="Operator =="];
85 [label="Exit left part of ||"];
86 [label="Enter right part of ||"];
87 [label="Function call: R|java/lang/Exception.Exception|()"];
88 [label="Throw: throw R|java/lang/Exception.Exception|()"];
89 [label="Stub" style="filled" fillcolor=gray];
90 [label="Exit ||"];
}
91 [label="Access variable R|<local>/a|"];
92 [label="Function call: R|<local>/a|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()"];
93 [label="Exit function test_5" style="filled" fillcolor=red];
}
80 -> {81};
81 -> {82};
82 -> {83};
83 -> {84};
84 -> {85};
85 -> {90 86};
86 -> {87};
87 -> {88};
88 -> {93};
88 -> {89} [style=dotted];
89 -> {90} [style=dotted];
90 -> {91};
91 -> {92};
92 -> {93};
subgraph cluster_17 {
color=red
94 [label="Enter function teat_6" style="filled" fillcolor=red];
subgraph cluster_18 {
color=blue
95 [label="Enter &&"];
96 [label="Access variable R|<local>/a|"];
97 [label="Const: Null(null)"];
98 [label="Operator !="];
99 [label="Exit left part of &&"];
100 [label="Enter right part of &&"];
101 [label="Function call: R|java/lang/Exception.Exception|()"];
102 [label="Throw: throw R|java/lang/Exception.Exception|()"];
103 [label="Stub" style="filled" fillcolor=gray];
104 [label="Exit &&"];
}
105 [label="Access variable R|<local>/a|"];
106 [label="Function call: R|<local>/a|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()"];
107 [label="Exit function teat_6" style="filled" fillcolor=red];
}
94 -> {95};
95 -> {96};
96 -> {97};
97 -> {98};
98 -> {99};
99 -> {104 100};
100 -> {101};
101 -> {102};
102 -> {107};
102 -> {103} [style=dotted];
103 -> {104} [style=dotted];
104 -> {105};
105 -> {106};
106 -> {107};
subgraph cluster_19 {
color=red
108 [label="Enter function test_7" style="filled" fillcolor=red];
subgraph cluster_20 {
color=blue
109 [label="Enter when"];
subgraph cluster_21 {
color=blue
110 [label="Enter when branch condition "];
subgraph cluster_22 {
color=blue
111 [label="Enter ||"];
112 [label="Access variable R|<local>/a|"];
113 [label="Const: Null(null)"];
114 [label="Operator =="];
115 [label="Exit left part of ||"];
116 [label="Enter right part of ||"];
117 [label="Function call: R|java/lang/Exception.Exception|()"];
118 [label="Throw: throw R|java/lang/Exception.Exception|()"];
119 [label="Stub" style="filled" fillcolor=gray];
120 [label="Exit ||"];
}
121 [label="Exit when branch condition"];
}
122 [label="Synthetic else branch"];
123 [label="Enter when branch result"];
subgraph cluster_23 {
color=blue
124 [label="Enter block"];
125 [label="Access variable R|<local>/a|"];
126 [label="Function call: R|<local>/a|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()"];
127 [label="Exit block"];
}
128 [label="Exit when branch result"];
129 [label="Exit when"];
}
130 [label="Access variable R|<local>/a|"];
131 [label="Function call: R|<local>/a|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()"];
132 [label="Exit function test_7" style="filled" fillcolor=red];
}
108 -> {109};
109 -> {110};
110 -> {111};
111 -> {112};
112 -> {113};
113 -> {114};
114 -> {115};
115 -> {120 116};
116 -> {117};
117 -> {118};
118 -> {132};
118 -> {119} [style=dotted];
119 -> {120} [style=dotted];
120 -> {121};
121 -> {123 122};
122 -> {129};
123 -> {124};
124 -> {125};
125 -> {126};
126 -> {127};
127 -> {128};
128 -> {129};
129 -> {130};
130 -> {131};
131 -> {132};
subgraph cluster_24 {
color=red
133 [label="Enter function test_8" style="filled" fillcolor=red];
subgraph cluster_25 {
color=blue
134 [label="Enter when"];
subgraph cluster_26 {
color=blue
135 [label="Enter when branch condition "];
subgraph cluster_27 {
color=blue
136 [label="Enter &&"];
137 [label="Access variable R|<local>/a|"];
138 [label="Const: Null(null)"];
139 [label="Operator !="];
140 [label="Exit left part of &&"];
141 [label="Enter right part of &&"];
142 [label="Function call: R|java/lang/Exception.Exception|()"];
143 [label="Throw: throw R|java/lang/Exception.Exception|()"];
144 [label="Stub" style="filled" fillcolor=gray];
145 [label="Exit &&"];
}
146 [label="Exit when branch condition"];
}
147 [label="Synthetic else branch"];
148 [label="Enter when branch result"];
subgraph cluster_28 {
color=blue
149 [label="Enter block"];
150 [label="Access variable R|<local>/a|"];
151 [label="Function call: R|<local>/a|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()"];
152 [label="Exit block"];
}
153 [label="Exit when branch result"];
154 [label="Exit when"];
}
155 [label="Access variable R|<local>/a|"];
156 [label="Function call: R|<local>/a|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()"];
157 [label="Exit function test_8" style="filled" fillcolor=red];
}
133 -> {134};
134 -> {135};
135 -> {136};
136 -> {137};
137 -> {138};
138 -> {139};
139 -> {140};
140 -> {145 141};
141 -> {142};
142 -> {143};
143 -> {157};
143 -> {144} [style=dotted];
144 -> {145} [style=dotted];
145 -> {146};
146 -> {148 147};
147 -> {154};
148 -> {149};
149 -> {150};
150 -> {151};
151 -> {152};
152 -> {153};
153 -> {154};
154 -> {155};
155 -> {156};
156 -> {157};
}
@@ -0,0 +1,57 @@
// !DUMP_CFG
interface A {
fun foo()
}
// ------------------------- Should work -------------------------
fun test_1(a: A?) {
a != null || throw Exception()
a.foo()
}
fun teat_2(a: A?) {
a == null && throw Exception()
a.foo()
}
fun test_3(a: A?) {
if (a != null || throw Exception()) {
a.foo()
}
a.foo()
}
fun test_4(a: A?) {
if (a == null && throw Exception()) {
a.foo()
}
a.foo()
}
// ------------------------- Shouldn't work -------------------------
fun test_5(a: A?) {
a == null || throw Exception()
a.<!INAPPLICABLE_CANDIDATE!>foo<!>()
}
fun teat_6(a: A?) {
a != null && throw Exception()
a.<!INAPPLICABLE_CANDIDATE!>foo<!>()
}
fun test_7(a: A?) {
if (a == null || throw Exception()) {
a.<!INAPPLICABLE_CANDIDATE!>foo<!>()
}
a.<!INAPPLICABLE_CANDIDATE!>foo<!>()
}
fun test_8(a: A?) {
if (a != null && throw Exception()) {
a.<!INAPPLICABLE_CANDIDATE!>foo<!>()
}
a.<!INAPPLICABLE_CANDIDATE!>foo<!>()
}
@@ -0,0 +1,57 @@
FILE: jumpFromRhsOfOperator.kt
public abstract interface A : R|kotlin/Any| {
public abstract fun foo(): R|kotlin/Unit|
}
public final fun test_1(a: R|A?|): R|kotlin/Unit| {
!=(R|<local>/a|, Null(null)) || throw R|java/lang/Exception.Exception|()
R|<local>/a|.R|/A.foo|()
}
public final fun teat_2(a: R|A?|): R|kotlin/Unit| {
==(R|<local>/a|, Null(null)) && throw R|java/lang/Exception.Exception|()
R|<local>/a|.R|/A.foo|()
}
public final fun test_3(a: R|A?|): R|kotlin/Unit| {
when () {
!=(R|<local>/a|, Null(null)) || throw R|java/lang/Exception.Exception|() -> {
R|<local>/a|.R|/A.foo|()
}
}
R|<local>/a|.R|/A.foo|()
}
public final fun test_4(a: R|A?|): R|kotlin/Unit| {
when () {
==(R|<local>/a|, Null(null)) && throw R|java/lang/Exception.Exception|() -> {
R|<local>/a|.R|/A.foo|()
}
}
R|<local>/a|.R|/A.foo|()
}
public final fun test_5(a: R|A?|): R|kotlin/Unit| {
==(R|<local>/a|, Null(null)) || throw R|java/lang/Exception.Exception|()
R|<local>/a|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()
}
public final fun teat_6(a: R|A?|): R|kotlin/Unit| {
!=(R|<local>/a|, Null(null)) && throw R|java/lang/Exception.Exception|()
R|<local>/a|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()
}
public final fun test_7(a: R|A?|): R|kotlin/Unit| {
when () {
==(R|<local>/a|, Null(null)) || throw R|java/lang/Exception.Exception|() -> {
R|<local>/a|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()
}
}
R|<local>/a|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()
}
public final fun test_8(a: R|A?|): R|kotlin/Unit| {
when () {
!=(R|<local>/a|, Null(null)) && throw R|java/lang/Exception.Exception|() -> {
R|<local>/a|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()
}
}
R|<local>/a|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()
}
@@ -0,0 +1,483 @@
digraph boundSmartcasts_kt {
graph [nodesep=3]
node [shape=box penwidth=2]
edge [penwidth=2]
subgraph cluster_0 {
color=red
0 [label="Enter function foo" style="filled" fillcolor=red];
1 [label="Exit function foo" style="filled" fillcolor=red];
}
0 -> {1};
subgraph cluster_1 {
color=red
2 [label="Enter function bar" style="filled" fillcolor=red];
3 [label="Exit function bar" style="filled" fillcolor=red];
}
2 -> {3};
subgraph cluster_2 {
color=red
4 [label="Enter function test_1" style="filled" fillcolor=red];
5 [label="Access variable R|<local>/x|"];
6 [label="Variable declaration: lval y: R|kotlin/Any|"];
subgraph cluster_3 {
color=blue
7 [label="Enter when"];
subgraph cluster_4 {
color=blue
8 [label="Enter when branch condition "];
9 [label="Access variable R|<local>/x|"];
10 [label="Type operator: (R|<local>/x| is R|A|)"];
11 [label="Exit when branch condition"];
}
12 [label="Synthetic else branch"];
13 [label="Enter when branch result"];
subgraph cluster_5 {
color=blue
14 [label="Enter block"];
15 [label="Access variable R|<local>/x|"];
16 [label="Function call: R|<local>/x|.R|/A.foo|()"];
17 [label="Access variable R|<local>/y|"];
18 [label="Function call: R|<local>/y|.R|/A.foo|()"];
19 [label="Exit block"];
}
20 [label="Exit when branch result"];
21 [label="Exit when"];
}
22 [label="Exit function test_1" style="filled" fillcolor=red];
}
4 -> {5};
5 -> {6};
6 -> {7};
7 -> {8};
8 -> {9};
9 -> {10};
10 -> {11};
11 -> {13 12};
12 -> {21};
13 -> {14};
14 -> {15};
15 -> {16};
16 -> {17};
17 -> {18};
18 -> {19};
19 -> {20};
20 -> {21};
21 -> {22};
subgraph cluster_6 {
color=red
23 [label="Enter function test_2" style="filled" fillcolor=red];
24 [label="Access variable R|<local>/x|"];
25 [label="Variable declaration: lval y: R|kotlin/Any|"];
subgraph cluster_7 {
color=blue
26 [label="Enter when"];
subgraph cluster_8 {
color=blue
27 [label="Enter when branch condition "];
28 [label="Access variable R|<local>/y|"];
29 [label="Type operator: (R|<local>/y| is R|A|)"];
30 [label="Exit when branch condition"];
}
31 [label="Synthetic else branch"];
32 [label="Enter when branch result"];
subgraph cluster_9 {
color=blue
33 [label="Enter block"];
34 [label="Access variable R|<local>/x|"];
35 [label="Function call: R|<local>/x|.R|/A.foo|()"];
36 [label="Access variable R|<local>/y|"];
37 [label="Function call: R|<local>/y|.R|/A.foo|()"];
38 [label="Exit block"];
}
39 [label="Exit when branch result"];
40 [label="Exit when"];
}
41 [label="Exit function test_2" style="filled" fillcolor=red];
}
23 -> {24};
24 -> {25};
25 -> {26};
26 -> {27};
27 -> {28};
28 -> {29};
29 -> {30};
30 -> {32 31};
31 -> {40};
32 -> {33};
33 -> {34};
34 -> {35};
35 -> {36};
36 -> {37};
37 -> {38};
38 -> {39};
39 -> {40};
40 -> {41};
subgraph cluster_10 {
color=red
42 [label="Enter function test_3" style="filled" fillcolor=red];
43 [label="Access variable R|<local>/x|"];
44 [label="Variable declaration: lvar z: R|kotlin/Any|"];
subgraph cluster_11 {
color=blue
45 [label="Enter when"];
subgraph cluster_12 {
color=blue
46 [label="Enter when branch condition "];
47 [label="Access variable R|<local>/x|"];
48 [label="Type operator: (R|<local>/x| is R|A|)"];
49 [label="Exit when branch condition"];
}
50 [label="Synthetic else branch"];
51 [label="Enter when branch result"];
subgraph cluster_13 {
color=blue
52 [label="Enter block"];
53 [label="Access variable R|<local>/z|"];
54 [label="Function call: R|<local>/z|.R|/A.foo|()"];
55 [label="Exit block"];
}
56 [label="Exit when branch result"];
57 [label="Exit when"];
}
58 [label="Access variable R|<local>/y|"];
59 [label="Assignmenet: R|<local>/z|"];
subgraph cluster_14 {
color=blue
60 [label="Enter when"];
subgraph cluster_15 {
color=blue
61 [label="Enter when branch condition "];
62 [label="Access variable R|<local>/y|"];
63 [label="Type operator: (R|<local>/y| is R|B|)"];
64 [label="Exit when branch condition"];
}
65 [label="Synthetic else branch"];
66 [label="Enter when branch result"];
subgraph cluster_16 {
color=blue
67 [label="Enter block"];
68 [label="Access variable R|<local>/z|"];
69 [label="Function call: R|<local>/z|.<Unresolved name: foo>#()"];
70 [label="Access variable R|<local>/z|"];
71 [label="Function call: R|<local>/z|.R|/B.bar|()"];
72 [label="Exit block"];
}
73 [label="Exit when branch result"];
74 [label="Exit when"];
}
75 [label="Exit function test_3" style="filled" fillcolor=red];
}
42 -> {43};
43 -> {44};
44 -> {45};
45 -> {46};
46 -> {47};
47 -> {48};
48 -> {49};
49 -> {51 50};
50 -> {57};
51 -> {52};
52 -> {53};
53 -> {54};
54 -> {55};
55 -> {56};
56 -> {57};
57 -> {58};
58 -> {59};
59 -> {60};
60 -> {61};
61 -> {62};
62 -> {63};
63 -> {64};
64 -> {66 65};
65 -> {74};
66 -> {67};
67 -> {68};
68 -> {69};
69 -> {70};
70 -> {71};
71 -> {72};
72 -> {73};
73 -> {74};
74 -> {75};
subgraph cluster_17 {
color=red
76 [label="Enter function test_4" style="filled" fillcolor=red];
77 [label="Const: Int(1)"];
78 [label="Variable declaration: lvar x: R|kotlin/Any|"];
79 [label="Access variable R|<local>/x|"];
80 [label="Type operator: (R|<local>/x| as R|kotlin/Int|)"];
81 [label="Access variable R|<local>/x|"];
82 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()"];
83 [label="Access variable R|<local>/y|"];
84 [label="Assignmenet: R|<local>/x|"];
85 [label="Access variable R|<local>/x|"];
86 [label="Function call: R|<local>/x|.<Unresolved name: inc>#()"];
subgraph cluster_18 {
color=blue
87 [label="Enter when"];
subgraph cluster_19 {
color=blue
88 [label="Enter when branch condition "];
89 [label="Access variable R|<local>/y|"];
90 [label="Type operator: (R|<local>/y| is R|A|)"];
91 [label="Exit when branch condition"];
}
92 [label="Synthetic else branch"];
93 [label="Enter when branch result"];
subgraph cluster_20 {
color=blue
94 [label="Enter block"];
95 [label="Access variable R|<local>/x|"];
96 [label="Function call: R|<local>/x|.R|/A.foo|()"];
97 [label="Access variable R|<local>/y|"];
98 [label="Function call: R|<local>/y|.R|/A.foo|()"];
99 [label="Exit block"];
}
100 [label="Exit when branch result"];
101 [label="Exit when"];
}
102 [label="Exit function test_4" style="filled" fillcolor=red];
}
76 -> {77};
77 -> {78};
78 -> {79};
79 -> {80};
80 -> {81};
81 -> {82};
82 -> {83};
83 -> {84};
84 -> {85};
85 -> {86};
86 -> {87};
87 -> {88};
88 -> {89};
89 -> {90};
90 -> {91};
91 -> {93 92};
92 -> {101};
93 -> {94};
94 -> {95};
95 -> {96};
96 -> {97};
97 -> {98};
98 -> {99};
99 -> {100};
100 -> {101};
101 -> {102};
subgraph cluster_21 {
color=red
103 [label="Enter function <init>" style="filled" fillcolor=red];
104 [label="Delegated constructor call: super<R|kotlin/Any|>()"];
105 [label="Exit function <init>" style="filled" fillcolor=red];
}
103 -> {104};
104 -> {105};
subgraph cluster_22 {
color=red
106 [label="Enter function getter" style="filled" fillcolor=red];
107 [label="Exit function getter" style="filled" fillcolor=red];
}
106 -> {107};
subgraph cluster_23 {
color=red
108 [label="Enter property" style="filled" fillcolor=red];
109 [label="Access variable R|<local>/any|"];
110 [label="Exit property" style="filled" fillcolor=red];
}
108 -> {109};
109 -> {110};
subgraph cluster_24 {
color=red
111 [label="Enter function baz" style="filled" fillcolor=red];
112 [label="Exit function baz" style="filled" fillcolor=red];
}
111 -> {112};
subgraph cluster_25 {
color=red
113 [label="Enter function test_5" style="filled" fillcolor=red];
subgraph cluster_26 {
color=blue
114 [label="Enter when"];
115 [label="Access variable R|<local>/d|"];
116 [label="Access variable R|/D.any|"];
117 [label="Variable declaration: lval <elvis>: R|kotlin/Any?|"];
subgraph cluster_27 {
color=blue
118 [label="Enter when branch condition "];
119 [label="Const: Null(null)"];
120 [label="Operator =="];
121 [label="Exit when branch condition"];
}
subgraph cluster_28 {
color=blue
122 [label="Enter when branch condition else"];
123 [label="Exit when branch condition"];
}
124 [label="Enter when branch result"];
subgraph cluster_29 {
color=blue
125 [label="Enter block"];
126 [label="Access variable R|<local>/<elvis>|"];
127 [label="Exit block"];
}
128 [label="Exit when branch result"];
129 [label="Enter when branch result"];
subgraph cluster_30 {
color=blue
130 [label="Enter block"];
131 [label="Jump: ^test_5 Unit"];
132 [label="Stub" style="filled" fillcolor=gray];
133 [label="Exit block" style="filled" fillcolor=gray];
}
134 [label="Exit when branch result" style="filled" fillcolor=gray];
135 [label="Exit when"];
}
136 [label="Variable declaration: lval a: R|kotlin/Any|"];
137 [label="Access variable R|<local>/a|"];
138 [label="Function call: R|<local>/a|.R|/baz|()"];
139 [label="Access variable R|<local>/d|"];
140 [label="Access variable R|/D.any|"];
141 [label="Function call: R|<local>/d|.R|/D.any|.R|/baz|()"];
142 [label="Access variable R|<local>/a|"];
143 [label="Type operator: (R|<local>/a| as R|A|)"];
144 [label="Access variable R|<local>/a|"];
145 [label="Function call: R|<local>/a|.R|/A.foo|()"];
146 [label="Exit function test_5" style="filled" fillcolor=red];
}
113 -> {114};
114 -> {115};
115 -> {116};
116 -> {117};
117 -> {118};
118 -> {119};
119 -> {120};
120 -> {121};
121 -> {129 122};
122 -> {123};
123 -> {124};
124 -> {125};
125 -> {126};
126 -> {127};
127 -> {128};
128 -> {135};
129 -> {130};
130 -> {131};
131 -> {146};
131 -> {132} [style=dotted];
132 -> {133} [style=dotted];
133 -> {134} [style=dotted];
134 -> {135} [style=dotted];
135 -> {136};
136 -> {137};
137 -> {138};
138 -> {139};
139 -> {140};
140 -> {141};
141 -> {142};
142 -> {143};
143 -> {144};
144 -> {145};
145 -> {146};
subgraph cluster_31 {
color=red
147 [label="Enter function test_6" style="filled" fillcolor=red];
148 [label="Access variable R|<local>/d1|"];
149 [label="Access variable R|/D.any|"];
150 [label="Variable declaration: lval a: R|kotlin/Any?|"];
151 [label="Access variable R|<local>/a|"];
152 [label="Type operator: (R|<local>/a| as R|A|)"];
153 [label="Access variable R|<local>/a|"];
154 [label="Function call: R|<local>/a|.R|/A.foo|()"];
155 [label="Access variable R|<local>/d1|"];
156 [label="Access variable R|/D.any|"];
157 [label="Function call: R|<local>/d1|.R|/D.any|.R|/A.foo|()"];
158 [label="Access variable R|<local>/d1|"];
159 [label="Access variable R|/D.any|"];
160 [label="Function call: R|<local>/d1|.R|/D.any|.R|/baz|()"];
161 [label="Exit function test_6" style="filled" fillcolor=red];
}
147 -> {148};
148 -> {149};
149 -> {150};
150 -> {151};
151 -> {152};
152 -> {153};
153 -> {154};
154 -> {155};
155 -> {156};
156 -> {157};
157 -> {158};
158 -> {159};
159 -> {160};
160 -> {161};
subgraph cluster_32 {
color=red
162 [label="Enter function test_7" style="filled" fillcolor=red];
163 [label="Access variable R|<local>/d1|"];
164 [label="Enter safe call"];
165 [label="Access variable R|/D.any|"];
166 [label="Exit safe call"];
167 [label="Variable declaration: lval a: R|kotlin/Any?|"];
168 [label="Access variable R|<local>/d2|"];
169 [label="Enter safe call"];
170 [label="Access variable R|/D.any|"];
171 [label="Exit safe call"];
172 [label="Variable declaration: lval b: R|kotlin/Any?|"];
173 [label="Access variable R|<local>/a|"];
174 [label="Type operator: (R|<local>/a| as R|A|)"];
175 [label="Access variable R|<local>/a|"];
176 [label="Function call: R|<local>/a|.R|/A.foo|()"];
177 [label="Access variable R|<local>/b|"];
178 [label="Type operator: (R|<local>/b| as R|B|)"];
179 [label="Access variable R|<local>/b|"];
180 [label="Function call: R|<local>/b|.R|/B.bar|()"];
181 [label="Exit function test_7" style="filled" fillcolor=red];
}
162 -> {163};
163 -> {164 166};
164 -> {165};
165 -> {166};
166 -> {167};
167 -> {168};
168 -> {169 171};
169 -> {170};
170 -> {171};
171 -> {172};
172 -> {173};
173 -> {174};
174 -> {175};
175 -> {176};
176 -> {177};
177 -> {178};
178 -> {179};
179 -> {180};
180 -> {181};
}
@@ -0,0 +1,78 @@
// !DUMP_CFG
interface A {
fun foo()
}
interface B {
fun bar()
}
fun test_1(x: Any) {
val y = x
if (x is A) {
x.foo()
y.foo()
}
}
fun test_2(x: Any) {
val y = x
if (y is A) {
x.foo()
y.foo()
}
}
fun test_3(x: Any, y: Any) {
var z = x
if (x is A) {
z.foo()
}
z = y
if (y is B) {
z.<!UNRESOLVED_REFERENCE!>foo<!>()
z.bar()
}
}
fun test_4(y: Any) {
var x: Any = 1
x as Int
x.inc()
x = y
x.<!UNRESOLVED_REFERENCE!>inc<!>()
if (y is A) {
x.foo()
y.foo()
}
}
class D(val any: Any?)
fun Any.baz() {}
fun test_5(d: D) {
// Elvis operator is converted into == function call
val a = d.any ?: return
a.baz() // should be OK
d.any.baz() // should be OK
a as A
a.foo() // should be OK
}
fun test_6(d1: D) {
val a = d1.any
a as A
a.foo() // should be OK
d1.any.foo() // should be OK
d1.any.baz() // should be OK
}
fun test_7(d1: D, d2: D) {
val a = d1?.any
val b = d2?.any
a as A
a.foo() // should be OK
b as B
b.bar() // should be OK
}
@@ -0,0 +1,101 @@
FILE: boundSmartcasts.kt
public abstract interface A : R|kotlin/Any| {
public abstract fun foo(): R|kotlin/Unit|
}
public abstract interface B : R|kotlin/Any| {
public abstract fun bar(): R|kotlin/Unit|
}
public final fun test_1(x: R|kotlin/Any|): R|kotlin/Unit| {
lval y: R|kotlin/Any| = R|<local>/x|
when () {
(R|<local>/x| is R|A|) -> {
R|<local>/x|.R|/A.foo|()
R|<local>/y|.R|/A.foo|()
}
}
}
public final fun test_2(x: R|kotlin/Any|): R|kotlin/Unit| {
lval y: R|kotlin/Any| = R|<local>/x|
when () {
(R|<local>/y| is R|A|) -> {
R|<local>/x|.R|/A.foo|()
R|<local>/y|.R|/A.foo|()
}
}
}
public final fun test_3(x: R|kotlin/Any|, y: R|kotlin/Any|): R|kotlin/Unit| {
lvar z: R|kotlin/Any| = R|<local>/x|
when () {
(R|<local>/x| is R|A|) -> {
R|<local>/z|.R|/A.foo|()
}
}
R|<local>/z| = R|<local>/y|
when () {
(R|<local>/y| is R|B|) -> {
R|<local>/z|.<Unresolved name: foo>#()
R|<local>/z|.R|/B.bar|()
}
}
}
public final fun test_4(y: R|kotlin/Any|): R|kotlin/Unit| {
lvar x: R|kotlin/Any| = Int(1)
(R|<local>/x| as R|kotlin/Int|)
R|<local>/x|.R|kotlin/Int.inc|()
R|<local>/x| = R|<local>/y|
R|<local>/x|.<Unresolved name: inc>#()
when () {
(R|<local>/y| is R|A|) -> {
R|<local>/x|.R|/A.foo|()
R|<local>/y|.R|/A.foo|()
}
}
}
public final class D : R|kotlin/Any| {
public constructor(any: R|kotlin/Any?|): R|D| {
super<R|kotlin/Any|>()
}
public final val any: R|kotlin/Any?| = R|<local>/any|
public get(): R|kotlin/Any?|
}
public final fun R|kotlin/Any|.baz(): R|kotlin/Unit| {
}
public final fun test_5(d: R|D|): R|kotlin/Unit| {
lval a: R|kotlin/Any| = when (lval <elvis>: R|kotlin/Any?| = R|<local>/d|.R|/D.any|) {
==($subj$, Null(null)) -> {
^test_5 Unit
}
else -> {
R|<local>/<elvis>|
}
}
R|<local>/a|.R|/baz|()
R|<local>/d|.R|/D.any|.R|/baz|()
(R|<local>/a| as R|A|)
R|<local>/a|.R|/A.foo|()
}
public final fun test_6(d1: R|D|): R|kotlin/Unit| {
lval a: R|kotlin/Any?| = R|<local>/d1|.R|/D.any|
(R|<local>/a| as R|A|)
R|<local>/a|.R|/A.foo|()
R|<local>/d1|.R|/D.any|.R|/A.foo|()
R|<local>/d1|.R|/D.any|.R|/baz|()
}
public final fun test_7(d1: R|D|, d2: R|D|): R|kotlin/Unit| {
lval a: R|kotlin/Any?| = R|<local>/d1|?.R|/D.any|
lval b: R|kotlin/Any?| = R|<local>/d2|?.R|/D.any|
(R|<local>/a| as R|A|)
R|<local>/a|.R|/A.foo|()
(R|<local>/b| as R|B|)
R|<local>/b|.R|/B.bar|()
}
@@ -0,0 +1,807 @@
digraph boundSmartcastsInBranches_kt {
graph [nodesep=3]
node [shape=box penwidth=2]
edge [penwidth=2]
subgraph cluster_0 {
color=red
0 [label="Enter function <init>" style="filled" fillcolor=red];
1 [label="Delegated constructor call: super<R|kotlin/Any|>()"];
2 [label="Exit function <init>" style="filled" fillcolor=red];
}
0 -> {1};
1 -> {2};
subgraph cluster_1 {
color=red
3 [label="Enter function getter" style="filled" fillcolor=red];
4 [label="Exit function getter" style="filled" fillcolor=red];
}
3 -> {4};
subgraph cluster_2 {
color=red
5 [label="Enter property" style="filled" fillcolor=red];
6 [label="Const: String()"];
7 [label="Exit property" style="filled" fillcolor=red];
}
5 -> {6};
6 -> {7};
subgraph cluster_3 {
color=red
8 [label="Enter function test_0" style="filled" fillcolor=red];
9 [label="Const: Null(null)"];
10 [label="Variable declaration: lvar goodA: R|A?|"];
11 [label="Access variable R|<local>/list|"];
12 [label="Function call: R|<local>/list|.R|FakeOverride<kotlin/collections/List.iterator: R|kotlin/collections/Iterator<A>|>|()"];
13 [label="Variable declaration: lval <iterator>: R|kotlin/collections/Iterator<A>|"];
subgraph cluster_4 {
color=blue
14 [label="Enter while loop"];
subgraph cluster_5 {
color=blue
15 [label="Enter loop condition"];
16 [label="Access variable R|<local>/<iterator>|"];
17 [label="Function call: R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()"];
18 [label="Exit loop condition"];
}
subgraph cluster_6 {
color=blue
19 [label="Enter loop block"];
subgraph cluster_7 {
color=blue
20 [label="Enter block"];
21 [label="Access variable R|<local>/<iterator>|"];
22 [label="Function call: R|<local>/<iterator>|.R|FakeOverride<kotlin/collections/Iterator.next: R|A|>|()"];
23 [label="Variable declaration: lval a: R|A|"];
subgraph cluster_8 {
color=blue
24 [label="Enter when"];
subgraph cluster_9 {
color=blue
25 [label="Enter when branch condition "];
26 [label="Access variable R|<local>/goodA|"];
27 [label="Const: Null(null)"];
28 [label="Operator =="];
29 [label="Exit when branch condition"];
}
30 [label="Synthetic else branch"];
31 [label="Enter when branch result"];
subgraph cluster_10 {
color=blue
32 [label="Enter block"];
33 [label="Access variable R|<local>/a|"];
34 [label="Assignmenet: R|<local>/goodA|"];
35 [label="Jump: continue@@@[R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()] "];
36 [label="Stub" style="filled" fillcolor=gray];
37 [label="Exit block" style="filled" fillcolor=gray];
}
38 [label="Exit when branch result" style="filled" fillcolor=gray];
39 [label="Exit when"];
}
40 [label="Access variable R|<local>/goodA|"];
41 [label="Access variable R|/A.s|"];
42 [label="Exit block"];
}
43 [label="Exit loop block"];
}
44 [label="Exit whileloop"];
}
45 [label="Exit function test_0" style="filled" fillcolor=red];
}
8 -> {9};
9 -> {10};
10 -> {11};
11 -> {12};
12 -> {13};
13 -> {14};
14 -> {15};
15 -> {16};
16 -> {17};
17 -> {18};
18 -> {44 19};
19 -> {20};
20 -> {21};
21 -> {22};
22 -> {23};
23 -> {24};
24 -> {25};
25 -> {26};
26 -> {27};
27 -> {28};
28 -> {29};
29 -> {31 30};
30 -> {39};
31 -> {32};
32 -> {33};
33 -> {34};
34 -> {35};
35 -> {14};
35 -> {36} [style=dotted];
36 -> {37} [style=dotted];
37 -> {38} [style=dotted];
38 -> {39} [style=dotted];
39 -> {40};
40 -> {41};
41 -> {42};
42 -> {43};
43 -> {15};
44 -> {45};
subgraph cluster_11 {
color=red
46 [label="Enter function test_1" style="filled" fillcolor=red];
47 [label="Variable declaration: lval x: R|kotlin/Any|"];
subgraph cluster_12 {
color=blue
48 [label="Enter when"];
subgraph cluster_13 {
color=blue
49 [label="Enter when branch condition "];
50 [label="Access variable R|<local>/b|"];
51 [label="Exit when branch condition"];
}
subgraph cluster_14 {
color=blue
52 [label="Enter when branch condition else"];
53 [label="Exit when branch condition"];
}
54 [label="Enter when branch result"];
subgraph cluster_15 {
color=blue
55 [label="Enter block"];
56 [label="Access variable R|<local>/a|"];
57 [label="Assignmenet: R|<local>/x|"];
58 [label="Exit block"];
}
59 [label="Exit when branch result"];
60 [label="Enter when branch result"];
subgraph cluster_16 {
color=blue
61 [label="Enter block"];
62 [label="Function call: R|/A.A|()"];
63 [label="Assignmenet: R|<local>/x|"];
64 [label="Exit block"];
}
65 [label="Exit when branch result"];
66 [label="Exit when"];
}
67 [label="Access variable R|<local>/x|"];
68 [label="Access variable R|/A.s|"];
69 [label="Exit function test_1" style="filled" fillcolor=red];
}
46 -> {47};
47 -> {48};
48 -> {49};
49 -> {50};
50 -> {51};
51 -> {60 52};
52 -> {53};
53 -> {54};
54 -> {55};
55 -> {56};
56 -> {57};
57 -> {58};
58 -> {59};
59 -> {66};
60 -> {61};
61 -> {62};
62 -> {63};
63 -> {64};
64 -> {65};
65 -> {66};
66 -> {67};
67 -> {68};
68 -> {69};
subgraph cluster_17 {
color=red
70 [label="Enter function test_2" style="filled" fillcolor=red];
71 [label="Variable declaration: lval x: R|kotlin/Any|"];
subgraph cluster_18 {
color=blue
72 [label="Enter when"];
subgraph cluster_19 {
color=blue
73 [label="Enter when branch condition "];
74 [label="Access variable R|<local>/b|"];
75 [label="Exit when branch condition"];
}
subgraph cluster_20 {
color=blue
76 [label="Enter when branch condition else"];
77 [label="Exit when branch condition"];
}
78 [label="Enter when branch result"];
subgraph cluster_21 {
color=blue
79 [label="Enter block"];
80 [label="Access variable R|<local>/a|"];
81 [label="Assignmenet: R|<local>/x|"];
82 [label="Access variable R|<local>/a|"];
83 [label="Type operator: (R|<local>/a| as R|A|)"];
84 [label="Exit block"];
}
85 [label="Exit when branch result"];
86 [label="Enter when branch result"];
subgraph cluster_22 {
color=blue
87 [label="Enter block"];
88 [label="Function call: R|/A.A|()"];
89 [label="Assignmenet: R|<local>/x|"];
90 [label="Exit block"];
}
91 [label="Exit when branch result"];
92 [label="Exit when"];
}
93 [label="Access variable R|<local>/x|"];
94 [label="Access variable R|/A.s|"];
95 [label="Exit function test_2" style="filled" fillcolor=red];
}
70 -> {71};
71 -> {72};
72 -> {73};
73 -> {74};
74 -> {75};
75 -> {86 76};
76 -> {77};
77 -> {78};
78 -> {79};
79 -> {80};
80 -> {81};
81 -> {82};
82 -> {83};
83 -> {84};
84 -> {85};
85 -> {92};
86 -> {87};
87 -> {88};
88 -> {89};
89 -> {90};
90 -> {91};
91 -> {92};
92 -> {93};
93 -> {94};
94 -> {95};
subgraph cluster_23 {
color=red
96 [label="Enter function test_3" style="filled" fillcolor=red];
97 [label="Variable declaration: lval x: R|kotlin/Any|"];
subgraph cluster_24 {
color=blue
98 [label="Enter when"];
subgraph cluster_25 {
color=blue
99 [label="Enter when branch condition "];
100 [label="Access variable R|<local>/b|"];
101 [label="Exit when branch condition"];
}
subgraph cluster_26 {
color=blue
102 [label="Enter when branch condition else"];
103 [label="Exit when branch condition"];
}
104 [label="Enter when branch result"];
subgraph cluster_27 {
color=blue
105 [label="Enter block"];
106 [label="Access variable R|<local>/a|"];
107 [label="Type operator: (R|<local>/a| as R|A|)"];
108 [label="Access variable R|<local>/a|"];
109 [label="Assignmenet: R|<local>/x|"];
110 [label="Exit block"];
}
111 [label="Exit when branch result"];
112 [label="Enter when branch result"];
subgraph cluster_28 {
color=blue
113 [label="Enter block"];
114 [label="Function call: R|/A.A|()"];
115 [label="Assignmenet: R|<local>/x|"];
116 [label="Exit block"];
}
117 [label="Exit when branch result"];
118 [label="Exit when"];
}
119 [label="Access variable R|<local>/x|"];
120 [label="Access variable R|/A.s|"];
121 [label="Exit function test_3" style="filled" fillcolor=red];
}
96 -> {97};
97 -> {98};
98 -> {99};
99 -> {100};
100 -> {101};
101 -> {112 102};
102 -> {103};
103 -> {104};
104 -> {105};
105 -> {106};
106 -> {107};
107 -> {108};
108 -> {109};
109 -> {110};
110 -> {111};
111 -> {118};
112 -> {113};
113 -> {114};
114 -> {115};
115 -> {116};
116 -> {117};
117 -> {118};
118 -> {119};
119 -> {120};
120 -> {121};
subgraph cluster_29 {
color=red
122 [label="Enter function test_4" style="filled" fillcolor=red];
123 [label="Variable declaration: lval x: R|kotlin/Any|"];
subgraph cluster_30 {
color=blue
124 [label="Enter when"];
subgraph cluster_31 {
color=blue
125 [label="Enter when branch condition "];
126 [label="Access variable R|<local>/b|"];
127 [label="Exit when branch condition"];
}
subgraph cluster_32 {
color=blue
128 [label="Enter when branch condition else"];
129 [label="Exit when branch condition"];
}
130 [label="Enter when branch result"];
subgraph cluster_33 {
color=blue
131 [label="Enter block"];
132 [label="Access variable R|<local>/a|"];
133 [label="Assignmenet: R|<local>/x|"];
134 [label="Exit block"];
}
135 [label="Exit when branch result"];
136 [label="Enter when branch result"];
subgraph cluster_34 {
color=blue
137 [label="Enter block"];
138 [label="Access variable R|<local>/a|"];
139 [label="Assignmenet: R|<local>/x|"];
140 [label="Exit block"];
}
141 [label="Exit when branch result"];
142 [label="Exit when"];
}
143 [label="Access variable R|<local>/x|"];
144 [label="Type operator: (R|<local>/x| as R|A|)"];
145 [label="Access variable R|<local>/x|"];
146 [label="Access variable R|/A.s|"];
147 [label="Access variable R|<local>/a|"];
148 [label="Access variable R|/A.s|"];
149 [label="Exit function test_4" style="filled" fillcolor=red];
}
122 -> {123};
123 -> {124};
124 -> {125};
125 -> {126};
126 -> {127};
127 -> {136 128};
128 -> {129};
129 -> {130};
130 -> {131};
131 -> {132};
132 -> {133};
133 -> {134};
134 -> {135};
135 -> {142};
136 -> {137};
137 -> {138};
138 -> {139};
139 -> {140};
140 -> {141};
141 -> {142};
142 -> {143};
143 -> {144};
144 -> {145};
145 -> {146};
146 -> {147};
147 -> {148};
148 -> {149};
subgraph cluster_35 {
color=red
150 [label="Enter function test_5" style="filled" fillcolor=red];
151 [label="Variable declaration: lval x: R|kotlin/Any|"];
subgraph cluster_36 {
color=blue
152 [label="Enter when"];
subgraph cluster_37 {
color=blue
153 [label="Enter when branch condition "];
154 [label="Access variable R|<local>/b|"];
155 [label="Exit when branch condition"];
}
subgraph cluster_38 {
color=blue
156 [label="Enter when branch condition else"];
157 [label="Exit when branch condition"];
}
158 [label="Enter when branch result"];
subgraph cluster_39 {
color=blue
159 [label="Enter block"];
160 [label="Access variable R|<local>/a|"];
161 [label="Assignmenet: R|<local>/x|"];
162 [label="Exit block"];
}
163 [label="Exit when branch result"];
164 [label="Enter when branch result"];
subgraph cluster_40 {
color=blue
165 [label="Enter block"];
166 [label="Access variable R|<local>/a|"];
167 [label="Assignmenet: R|<local>/x|"];
168 [label="Exit block"];
}
169 [label="Exit when branch result"];
170 [label="Exit when"];
}
171 [label="Access variable R|<local>/a|"];
172 [label="Type operator: (R|<local>/a| as R|A|)"];
173 [label="Access variable R|<local>/x|"];
174 [label="Access variable R|/A.s|"];
175 [label="Access variable R|<local>/a|"];
176 [label="Access variable R|/A.s|"];
177 [label="Exit function test_5" style="filled" fillcolor=red];
}
150 -> {151};
151 -> {152};
152 -> {153};
153 -> {154};
154 -> {155};
155 -> {164 156};
156 -> {157};
157 -> {158};
158 -> {159};
159 -> {160};
160 -> {161};
161 -> {162};
162 -> {163};
163 -> {170};
164 -> {165};
165 -> {166};
166 -> {167};
167 -> {168};
168 -> {169};
169 -> {170};
170 -> {171};
171 -> {172};
172 -> {173};
173 -> {174};
174 -> {175};
175 -> {176};
176 -> {177};
subgraph cluster_41 {
color=red
178 [label="Enter function test_6" style="filled" fillcolor=red];
179 [label="Variable declaration: lval x: R|kotlin/Any|"];
180 [label="Access variable R|<local>/a|"];
181 [label="Assignmenet: R|<local>/x|"];
182 [label="Access variable R|<local>/x|"];
183 [label="Access variable R|/A.s|"];
184 [label="Exit function test_6" style="filled" fillcolor=red];
}
178 -> {179};
179 -> {180};
180 -> {181};
181 -> {182};
182 -> {183};
183 -> {184};
subgraph cluster_42 {
color=red
185 [label="Enter function test_7" style="filled" fillcolor=red];
186 [label="Const: Null(null)"];
187 [label="Variable declaration: lval z: R|kotlin/String?|"];
188 [label="Access variable R|<local>/z|"];
189 [label="Variable declaration: lvar y: R|kotlin/String?|"];
190 [label="Access variable R|<local>/y|"];
191 [label="Variable declaration: lval x: R|kotlin/String?|"];
subgraph cluster_43 {
color=blue
192 [label="Enter when"];
subgraph cluster_44 {
color=blue
193 [label="Enter when branch condition "];
194 [label="Access variable R|<local>/x|"];
195 [label="Const: Null(null)"];
196 [label="Operator !="];
197 [label="Exit when branch condition"];
}
198 [label="Synthetic else branch"];
199 [label="Enter when branch result"];
subgraph cluster_45 {
color=blue
200 [label="Enter block"];
201 [label="Access variable R|<local>/x|"];
202 [label="Access variable R|kotlin/String.length|"];
203 [label="Access variable R|<local>/y|"];
204 [label="Access variable R|kotlin/String.length|"];
205 [label="Access variable R|<local>/z|"];
206 [label="Access variable R|kotlin/String.length|"];
207 [label="Exit block"];
}
208 [label="Exit when branch result"];
209 [label="Exit when"];
}
subgraph cluster_46 {
color=blue
210 [label="Enter when"];
subgraph cluster_47 {
color=blue
211 [label="Enter when branch condition "];
212 [label="Access variable R|<local>/y|"];
213 [label="Const: Null(null)"];
214 [label="Operator !="];
215 [label="Exit when branch condition"];
}
216 [label="Synthetic else branch"];
217 [label="Enter when branch result"];
subgraph cluster_48 {
color=blue
218 [label="Enter block"];
219 [label="Access variable R|<local>/x|"];
220 [label="Access variable R|kotlin/String.length|"];
221 [label="Access variable R|<local>/y|"];
222 [label="Access variable R|kotlin/String.length|"];
223 [label="Access variable R|<local>/z|"];
224 [label="Access variable R|kotlin/String.length|"];
225 [label="Exit block"];
}
226 [label="Exit when branch result"];
227 [label="Exit when"];
}
subgraph cluster_49 {
color=blue
228 [label="Enter when"];
subgraph cluster_50 {
color=blue
229 [label="Enter when branch condition "];
230 [label="Access variable R|<local>/z|"];
231 [label="Const: Null(null)"];
232 [label="Operator !="];
233 [label="Exit when branch condition"];
}
234 [label="Synthetic else branch"];
235 [label="Enter when branch result"];
subgraph cluster_51 {
color=blue
236 [label="Enter block"];
237 [label="Access variable R|<local>/x|"];
238 [label="Access variable R|kotlin/String.length|"];
239 [label="Access variable R|<local>/y|"];
240 [label="Access variable R|kotlin/String.length|"];
241 [label="Access variable R|<local>/z|"];
242 [label="Access variable R|kotlin/String.length|"];
243 [label="Exit block"];
}
244 [label="Exit when branch result"];
245 [label="Exit when"];
}
246 [label="Const: Null(null)"];
247 [label="Assignmenet: R|<local>/y|"];
subgraph cluster_52 {
color=blue
248 [label="Enter when"];
subgraph cluster_53 {
color=blue
249 [label="Enter when branch condition "];
250 [label="Access variable R|<local>/x|"];
251 [label="Const: Null(null)"];
252 [label="Operator !="];
253 [label="Exit when branch condition"];
}
254 [label="Synthetic else branch"];
255 [label="Enter when branch result"];
subgraph cluster_54 {
color=blue
256 [label="Enter block"];
257 [label="Access variable R|<local>/x|"];
258 [label="Access variable R|kotlin/String.length|"];
259 [label="Access variable R|<local>/y|"];
260 [label="Access variable <Inapplicable(WRONG_RECEIVER): [kotlin/String.length]>#"];
261 [label="Access variable R|<local>/z|"];
262 [label="Access variable R|kotlin/String.length|"];
263 [label="Exit block"];
}
264 [label="Exit when branch result"];
265 [label="Exit when"];
}
subgraph cluster_55 {
color=blue
266 [label="Enter when"];
subgraph cluster_56 {
color=blue
267 [label="Enter when branch condition "];
268 [label="Access variable R|<local>/y|"];
269 [label="Const: Null(null)"];
270 [label="Operator !="];
271 [label="Exit when branch condition"];
}
272 [label="Synthetic else branch"];
273 [label="Enter when branch result"];
subgraph cluster_57 {
color=blue
274 [label="Enter block"];
275 [label="Access variable R|<local>/x|"];
276 [label="Access variable <Inapplicable(WRONG_RECEIVER): [kotlin/String.length]>#"];
277 [label="Access variable R|<local>/y|"];
278 [label="Access variable R|kotlin/String.length|"];
279 [label="Access variable R|<local>/z|"];
280 [label="Access variable <Inapplicable(WRONG_RECEIVER): [kotlin/String.length]>#"];
281 [label="Exit block"];
}
282 [label="Exit when branch result"];
283 [label="Exit when"];
}
subgraph cluster_58 {
color=blue
284 [label="Enter when"];
subgraph cluster_59 {
color=blue
285 [label="Enter when branch condition "];
286 [label="Access variable R|<local>/z|"];
287 [label="Const: Null(null)"];
288 [label="Operator !="];
289 [label="Exit when branch condition"];
}
290 [label="Synthetic else branch"];
291 [label="Enter when branch result"];
subgraph cluster_60 {
color=blue
292 [label="Enter block"];
293 [label="Access variable R|<local>/x|"];
294 [label="Access variable R|kotlin/String.length|"];
295 [label="Access variable R|<local>/y|"];
296 [label="Access variable <Inapplicable(WRONG_RECEIVER): [kotlin/String.length]>#"];
297 [label="Access variable R|<local>/z|"];
298 [label="Access variable R|kotlin/String.length|"];
299 [label="Exit block"];
}
300 [label="Exit when branch result"];
301 [label="Exit when"];
}
302 [label="Exit function test_7" style="filled" fillcolor=red];
}
185 -> {186};
186 -> {187};
187 -> {188};
188 -> {189};
189 -> {190};
190 -> {191};
191 -> {192};
192 -> {193};
193 -> {194};
194 -> {195};
195 -> {196};
196 -> {197};
197 -> {199 198};
198 -> {209};
199 -> {200};
200 -> {201};
201 -> {202};
202 -> {203};
203 -> {204};
204 -> {205};
205 -> {206};
206 -> {207};
207 -> {208};
208 -> {209};
209 -> {210};
210 -> {211};
211 -> {212};
212 -> {213};
213 -> {214};
214 -> {215};
215 -> {217 216};
216 -> {227};
217 -> {218};
218 -> {219};
219 -> {220};
220 -> {221};
221 -> {222};
222 -> {223};
223 -> {224};
224 -> {225};
225 -> {226};
226 -> {227};
227 -> {228};
228 -> {229};
229 -> {230};
230 -> {231};
231 -> {232};
232 -> {233};
233 -> {235 234};
234 -> {245};
235 -> {236};
236 -> {237};
237 -> {238};
238 -> {239};
239 -> {240};
240 -> {241};
241 -> {242};
242 -> {243};
243 -> {244};
244 -> {245};
245 -> {246};
246 -> {247};
247 -> {248};
248 -> {249};
249 -> {250};
250 -> {251};
251 -> {252};
252 -> {253};
253 -> {255 254};
254 -> {265};
255 -> {256};
256 -> {257};
257 -> {258};
258 -> {259};
259 -> {260};
260 -> {261};
261 -> {262};
262 -> {263};
263 -> {264};
264 -> {265};
265 -> {266};
266 -> {267};
267 -> {268};
268 -> {269};
269 -> {270};
270 -> {271};
271 -> {273 272};
272 -> {283};
273 -> {274};
274 -> {275};
275 -> {276};
276 -> {277};
277 -> {278};
278 -> {279};
279 -> {280};
280 -> {281};
281 -> {282};
282 -> {283};
283 -> {284};
284 -> {285};
285 -> {286};
286 -> {287};
287 -> {288};
288 -> {289};
289 -> {291 290};
290 -> {301};
291 -> {292};
292 -> {293};
293 -> {294};
294 -> {295};
295 -> {296};
296 -> {297};
297 -> {298};
298 -> {299};
299 -> {300};
300 -> {301};
301 -> {302};
}
@@ -0,0 +1,121 @@
// !DUMP_CFG
class A {
val s: String = ""
}
fun test_0(list: List<A>) {
var goodA: A? = null
for (a in list) {
if (goodA == null) {
goodA = a
continue
}
goodA.s
}
}
fun test_1(a: A, b: Boolean) {
val x: Any
if (b) {
x = A()
} else {
x = a
}
x.s
}
fun test_2(a: Any, b: Boolean) {
val x: Any
if (b) {
//x1
x = A()
} else {
//x2 = a
x = a
a as A
}
x.s
}
fun test_3(a: Any, b: Boolean) {
val x: Any
if (b) {
x = A()
} else {
a as A
x = a
}
x.s
}
fun test_4(a: Any, b: Boolean) {
val x: Any
if (b) {
x = a
} else {
x = a
}
x as A
x.s
a.s
}
fun test_5(a: Any, b: Boolean) {
val x: Any
if (b) {
x = a
} else {
x = a
}
a as A
x.s
a.s
}
fun test_6(a: A) {
val x: Any
x = a
x.s
}
fun test_7() {
val z: String? = null
var y : String? = z
val x: String? = y
if (x != null) {
x.length // OK
y.length // OK
z.length // OK
}
if (y != null) {
x.length // OK
y.length // OK
z.length // OK
}
if (z != null) {
x.length // OK
y.length // OK
z.length // OK
}
y = null
if (x != null) {
x.length // OK
y.<!INAPPLICABLE_CANDIDATE!>length<!> // Bad
z.length // OK
}
if (y != null) {
x.<!INAPPLICABLE_CANDIDATE!>length<!> // Bad
y.length // OK
z.<!INAPPLICABLE_CANDIDATE!>length<!> // Bad
}
if (z != null) {
x.length // OK
y.<!INAPPLICABLE_CANDIDATE!>length<!> // Bad
z.length // OK
}
}
@@ -0,0 +1,156 @@
FILE: boundSmartcastsInBranches.kt
public final class A : R|kotlin/Any| {
public constructor(): R|A| {
super<R|kotlin/Any|>()
}
public final val s: R|kotlin/String| = String()
public get(): R|kotlin/String|
}
public final fun test_0(list: R|kotlin/collections/List<A>|): R|kotlin/Unit| {
lvar goodA: R|A?| = Null(null)
lval <iterator>: R|kotlin/collections/Iterator<A>| = R|<local>/list|.R|FakeOverride<kotlin/collections/List.iterator: R|kotlin/collections/Iterator<A>|>|()
while(R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()) {
lval a: R|A| = R|<local>/<iterator>|.R|FakeOverride<kotlin/collections/Iterator.next: R|A|>|()
when () {
==(R|<local>/goodA|, Null(null)) -> {
R|<local>/goodA| = R|<local>/a|
continue@@@[R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()]
}
}
R|<local>/goodA|.R|/A.s|
}
}
public final fun test_1(a: R|A|, b: R|kotlin/Boolean|): R|kotlin/Unit| {
lval x: R|kotlin/Any|
when () {
R|<local>/b| -> {
R|<local>/x| = R|/A.A|()
}
else -> {
R|<local>/x| = R|<local>/a|
}
}
R|<local>/x|.R|/A.s|
}
public final fun test_2(a: R|kotlin/Any|, b: R|kotlin/Boolean|): R|kotlin/Unit| {
lval x: R|kotlin/Any|
when () {
R|<local>/b| -> {
R|<local>/x| = R|/A.A|()
}
else -> {
R|<local>/x| = R|<local>/a|
(R|<local>/a| as R|A|)
}
}
R|<local>/x|.R|/A.s|
}
public final fun test_3(a: R|kotlin/Any|, b: R|kotlin/Boolean|): R|kotlin/Unit| {
lval x: R|kotlin/Any|
when () {
R|<local>/b| -> {
R|<local>/x| = R|/A.A|()
}
else -> {
(R|<local>/a| as R|A|)
R|<local>/x| = R|<local>/a|
}
}
R|<local>/x|.R|/A.s|
}
public final fun test_4(a: R|kotlin/Any|, b: R|kotlin/Boolean|): R|kotlin/Unit| {
lval x: R|kotlin/Any|
when () {
R|<local>/b| -> {
R|<local>/x| = R|<local>/a|
}
else -> {
R|<local>/x| = R|<local>/a|
}
}
(R|<local>/x| as R|A|)
R|<local>/x|.R|/A.s|
R|<local>/a|.R|/A.s|
}
public final fun test_5(a: R|kotlin/Any|, b: R|kotlin/Boolean|): R|kotlin/Unit| {
lval x: R|kotlin/Any|
when () {
R|<local>/b| -> {
R|<local>/x| = R|<local>/a|
}
else -> {
R|<local>/x| = R|<local>/a|
}
}
(R|<local>/a| as R|A|)
R|<local>/x|.R|/A.s|
R|<local>/a|.R|/A.s|
}
public final fun test_6(a: R|A|): R|kotlin/Unit| {
lval x: R|kotlin/Any|
R|<local>/x| = R|<local>/a|
R|<local>/x|.R|/A.s|
}
public final fun test_7(): R|kotlin/Unit| {
lval z: R|kotlin/String?| = Null(null)
lvar y: R|kotlin/String?| = R|<local>/z|
lval x: R|kotlin/String?| = R|<local>/y|
when () {
!=(R|<local>/x|, Null(null)) -> {
R|<local>/x|.R|kotlin/String.length|
R|<local>/y|.R|kotlin/String.length|
R|<local>/z|.R|kotlin/String.length|
}
}
when () {
!=(R|<local>/y|, Null(null)) -> {
R|<local>/x|.R|kotlin/String.length|
R|<local>/y|.R|kotlin/String.length|
R|<local>/z|.R|kotlin/String.length|
}
}
when () {
!=(R|<local>/z|, Null(null)) -> {
R|<local>/x|.R|kotlin/String.length|
R|<local>/y|.R|kotlin/String.length|
R|<local>/z|.R|kotlin/String.length|
}
}
R|<local>/y| = Null(null)
when () {
!=(R|<local>/x|, Null(null)) -> {
R|<local>/x|.R|kotlin/String.length|
R|<local>/y|.<Inapplicable(WRONG_RECEIVER): [kotlin/String.length]>#
R|<local>/z|.R|kotlin/String.length|
}
}
when () {
!=(R|<local>/y|, Null(null)) -> {
R|<local>/x|.<Inapplicable(WRONG_RECEIVER): [kotlin/String.length]>#
R|<local>/y|.R|kotlin/String.length|
R|<local>/z|.<Inapplicable(WRONG_RECEIVER): [kotlin/String.length]>#
}
}
when () {
!=(R|<local>/z|, Null(null)) -> {
R|<local>/x|.R|kotlin/String.length|
R|<local>/y|.<Inapplicable(WRONG_RECEIVER): [kotlin/String.length]>#
R|<local>/z|.R|kotlin/String.length|
}
}
}
@@ -0,0 +1,143 @@
digraph functionCallBound_kt {
graph [nodesep=3]
node [shape=box penwidth=2]
edge [penwidth=2]
subgraph cluster_0 {
color=red
0 [label="Enter function <init>" style="filled" fillcolor=red];
1 [label="Delegated constructor call: super<R|kotlin/Any|>()"];
2 [label="Exit function <init>" style="filled" fillcolor=red];
}
0 -> {1};
1 -> {2};
subgraph cluster_1 {
color=red
3 [label="Enter function <init>" style="filled" fillcolor=red];
4 [label="Delegated constructor call: super<R|Base|>()"];
5 [label="Exit function <init>" style="filled" fillcolor=red];
}
3 -> {4};
4 -> {5};
subgraph cluster_2 {
color=red
6 [label="Enter function getter" style="filled" fillcolor=red];
7 [label="Exit function getter" style="filled" fillcolor=red];
}
6 -> {7};
subgraph cluster_3 {
color=red
8 [label="Enter property" style="filled" fillcolor=red];
9 [label="Access variable R|<local>/data|"];
10 [label="Exit property" style="filled" fillcolor=red];
}
8 -> {9};
9 -> {10};
subgraph cluster_4 {
color=red
11 [label="Enter function isOk" style="filled" fillcolor=red];
12 [label="Const: Boolean(true)"];
13 [label="Jump: ^isOk Boolean(true)"];
14 [label="Stub" style="filled" fillcolor=gray];
15 [label="Exit function isOk" style="filled" fillcolor=red];
}
11 -> {12};
12 -> {13};
13 -> {15};
13 -> {14} [style=dotted];
14 -> {15} [style=dotted];
subgraph cluster_5 {
color=red
16 [label="Enter function check" style="filled" fillcolor=red];
subgraph cluster_6 {
color=blue
17 [label="Enter when"];
subgraph cluster_7 {
color=blue
18 [label="Enter when branch condition "];
19 [label="Access variable R|<local>/base|"];
20 [label="Type operator: (R|<local>/base| as? R|Sub|)"];
21 [label="Enter safe call"];
22 [label="Function call: (R|<local>/base| as? R|Sub|)?.R|/isOk|()"];
23 [label="Exit safe call"];
24 [label="Const: Boolean(true)"];
25 [label="Operator =="];
26 [label="Exit when branch condition"];
}
subgraph cluster_8 {
color=blue
27 [label="Enter when branch condition else"];
28 [label="Exit when branch condition"];
}
29 [label="Enter when branch result"];
subgraph cluster_9 {
color=blue
30 [label="Enter block"];
31 [label="Access variable R|<local>/base|"];
32 [label="Exit block"];
}
33 [label="Exit when branch result"];
34 [label="Enter when branch result"];
subgraph cluster_10 {
color=blue
35 [label="Enter block"];
36 [label="Access variable R|<local>/base|"];
37 [label="Access variable R|/Sub.data|"];
38 [label="Exit block"];
}
39 [label="Exit when branch result"];
40 [label="Exit when"];
}
41 [label="Jump: ^check when () {
==((R|<local>/base| as? R|Sub|)?.R|/isOk|(), Boolean(true)) -> {
R|<local>/base|.R|/Sub.data|
}
else -> {
R|<local>/base|
}
}
"];
42 [label="Stub" style="filled" fillcolor=gray];
43 [label="Exit function check" style="filled" fillcolor=red];
}
16 -> {17};
17 -> {18};
18 -> {19};
19 -> {20};
20 -> {21 23};
21 -> {22};
22 -> {23};
23 -> {24};
24 -> {25};
25 -> {26};
26 -> {34 27};
27 -> {28};
28 -> {29};
29 -> {30};
30 -> {31};
31 -> {32};
32 -> {33};
33 -> {40};
34 -> {35};
35 -> {36};
36 -> {37};
37 -> {38};
38 -> {39};
39 -> {40};
40 -> {41};
41 -> {43};
41 -> {42} [style=dotted];
42 -> {43} [style=dotted];
}
@@ -0,0 +1,18 @@
// !DUMP_CFG
open class Base
class Sub(val data: Base): Base()
fun Sub.isOk() = true
fun check(base: Base): Base =
when {
(base as? Sub)?.isOk() == true -> {
base.data
}
else -> {
base
}
}
@@ -0,0 +1,30 @@
FILE: functionCallBound.kt
public open class Base : R|kotlin/Any| {
public constructor(): R|Base| {
super<R|kotlin/Any|>()
}
}
public final class Sub : R|Base| {
public constructor(data: R|Base|): R|Sub| {
super<R|Base|>()
}
public final val data: R|Base| = R|<local>/data|
public get(): R|Base|
}
public final fun R|Sub|.isOk(): R|kotlin/Boolean| {
^isOk Boolean(true)
}
public final fun check(base: R|Base|): R|Base| {
^check when () {
==((R|<local>/base| as? R|Sub|)?.R|/isOk|(), Boolean(true)) -> {
R|<local>/base|.R|/Sub.data|
}
else -> {
R|<local>/base|
}
}
}
@@ -0,0 +1,371 @@
digraph casts_kt {
graph [nodesep=3]
node [shape=box penwidth=2]
edge [penwidth=2]
subgraph cluster_0 {
color=red
0 [label="Enter function test_1" style="filled" fillcolor=red];
1 [label="Access variable R|<local>/x|"];
2 [label="Type operator: (R|<local>/x| as R|kotlin/String|)"];
3 [label="Access variable R|<local>/x|"];
4 [label="Access variable R|kotlin/String.length|"];
5 [label="Exit function test_1" style="filled" fillcolor=red];
}
0 -> {1};
1 -> {2};
2 -> {3};
3 -> {4};
4 -> {5};
subgraph cluster_1 {
color=red
6 [label="Enter function test_2" style="filled" fillcolor=red];
subgraph cluster_2 {
color=blue
7 [label="Enter when"];
subgraph cluster_3 {
color=blue
8 [label="Enter when branch condition "];
9 [label="Access variable R|<local>/x|"];
10 [label="Type operator: (R|<local>/x| as R|kotlin/Boolean|)"];
11 [label="Exit when branch condition"];
}
12 [label="Synthetic else branch"];
13 [label="Enter when branch result"];
subgraph cluster_4 {
color=blue
14 [label="Enter block"];
15 [label="Access variable R|<local>/x|"];
16 [label="Function call: R|<local>/x|.R|kotlin/Boolean.not|()"];
17 [label="Exit block"];
}
18 [label="Exit when branch result"];
19 [label="Exit when"];
}
20 [label="Access variable R|<local>/x|"];
21 [label="Function call: R|<local>/x|.R|kotlin/Boolean.not|()"];
22 [label="Exit function test_2" style="filled" fillcolor=red];
}
6 -> {7};
7 -> {8};
8 -> {9};
9 -> {10};
10 -> {11};
11 -> {13 12};
12 -> {19};
13 -> {14};
14 -> {15};
15 -> {16};
16 -> {17};
17 -> {18};
18 -> {19};
19 -> {20};
20 -> {21};
21 -> {22};
subgraph cluster_5 {
color=red
23 [label="Enter function test_3" style="filled" fillcolor=red];
subgraph cluster_6 {
color=blue
24 [label="Enter when"];
subgraph cluster_7 {
color=blue
25 [label="Enter when branch condition "];
subgraph cluster_8 {
color=blue
26 [label="Enter &&"];
27 [label="Access variable R|<local>/b|"];
28 [label="Exit left part of &&"];
29 [label="Enter right part of &&"];
30 [label="Access variable R|<local>/x|"];
31 [label="Type operator: (R|<local>/x| as R|kotlin/Boolean|)"];
32 [label="Exit &&"];
}
33 [label="Exit when branch condition"];
}
34 [label="Synthetic else branch"];
35 [label="Enter when branch result"];
subgraph cluster_9 {
color=blue
36 [label="Enter block"];
37 [label="Access variable R|<local>/x|"];
38 [label="Function call: R|<local>/x|.R|kotlin/Boolean.not|()"];
39 [label="Exit block"];
}
40 [label="Exit when branch result"];
41 [label="Exit when"];
}
42 [label="Access variable R|<local>/x|"];
43 [label="Function call: R|<local>/x|.<Unresolved name: not>#()"];
subgraph cluster_10 {
color=blue
44 [label="Enter when"];
subgraph cluster_11 {
color=blue
45 [label="Enter when branch condition "];
subgraph cluster_12 {
color=blue
46 [label="Enter &&"];
47 [label="Access variable R|<local>/b|"];
48 [label="Exit left part of &&"];
49 [label="Enter right part of &&"];
50 [label="Access variable R|<local>/x|"];
51 [label="Type operator: (R|<local>/x| as R|kotlin/Boolean|)"];
52 [label="Const: Boolean(true)"];
53 [label="Operator =="];
54 [label="Exit &&"];
}
55 [label="Exit when branch condition"];
}
56 [label="Synthetic else branch"];
57 [label="Enter when branch result"];
subgraph cluster_13 {
color=blue
58 [label="Enter block"];
59 [label="Access variable R|<local>/x|"];
60 [label="Function call: R|<local>/x|.R|kotlin/Boolean.not|()"];
61 [label="Exit block"];
}
62 [label="Exit when branch result"];
63 [label="Exit when"];
}
64 [label="Access variable R|<local>/x|"];
65 [label="Function call: R|<local>/x|.<Unresolved name: not>#()"];
subgraph cluster_14 {
color=blue
66 [label="Enter when"];
subgraph cluster_15 {
color=blue
67 [label="Enter when branch condition "];
subgraph cluster_16 {
color=blue
68 [label="Enter ||"];
69 [label="Access variable R|<local>/b|"];
70 [label="Exit left part of ||"];
71 [label="Enter right part of ||"];
72 [label="Access variable R|<local>/x|"];
73 [label="Type operator: (R|<local>/x| as R|kotlin/Boolean|)"];
74 [label="Exit ||"];
}
75 [label="Exit when branch condition"];
}
76 [label="Synthetic else branch"];
77 [label="Enter when branch result"];
subgraph cluster_17 {
color=blue
78 [label="Enter block"];
79 [label="Access variable R|<local>/x|"];
80 [label="Function call: R|<local>/x|.<Unresolved name: not>#()"];
81 [label="Exit block"];
}
82 [label="Exit when branch result"];
83 [label="Exit when"];
}
84 [label="Access variable R|<local>/x|"];
85 [label="Function call: R|<local>/x|.<Unresolved name: not>#()"];
86 [label="Exit function test_3" style="filled" fillcolor=red];
}
23 -> {24};
24 -> {25};
25 -> {26};
26 -> {27};
27 -> {28};
28 -> {32 29};
29 -> {30};
30 -> {31};
31 -> {32};
32 -> {33};
33 -> {35 34};
34 -> {41};
35 -> {36};
36 -> {37};
37 -> {38};
38 -> {39};
39 -> {40};
40 -> {41};
41 -> {42};
42 -> {43};
43 -> {44};
44 -> {45};
45 -> {46};
46 -> {47};
47 -> {48};
48 -> {54 49};
49 -> {50};
50 -> {51};
51 -> {52};
52 -> {53};
53 -> {54};
54 -> {55};
55 -> {57 56};
56 -> {63};
57 -> {58};
58 -> {59};
59 -> {60};
60 -> {61};
61 -> {62};
62 -> {63};
63 -> {64};
64 -> {65};
65 -> {66};
66 -> {67};
67 -> {68};
68 -> {69};
69 -> {70};
70 -> {74 71};
71 -> {72};
72 -> {73};
73 -> {74};
74 -> {75};
75 -> {77 76};
76 -> {83};
77 -> {78};
78 -> {79};
79 -> {80};
80 -> {81};
81 -> {82};
82 -> {83};
83 -> {84};
84 -> {85};
85 -> {86};
subgraph cluster_18 {
color=red
87 [label="Enter function test_4" style="filled" fillcolor=red];
subgraph cluster_19 {
color=blue
88 [label="Enter when"];
subgraph cluster_20 {
color=blue
89 [label="Enter when branch condition "];
90 [label="Access variable R|<local>/b|"];
91 [label="Type operator: (R|<local>/b| as? R|kotlin/Boolean|)"];
92 [label="Const: Null(null)"];
93 [label="Operator !="];
94 [label="Exit when branch condition"];
}
subgraph cluster_21 {
color=blue
95 [label="Enter when branch condition else"];
96 [label="Exit when branch condition"];
}
97 [label="Enter when branch result"];
subgraph cluster_22 {
color=blue
98 [label="Enter block"];
99 [label="Access variable R|<local>/b|"];
100 [label="Function call: R|<local>/b|.<Unresolved name: not>#()"];
101 [label="Exit block"];
}
102 [label="Exit when branch result"];
103 [label="Enter when branch result"];
subgraph cluster_23 {
color=blue
104 [label="Enter block"];
105 [label="Access variable R|<local>/b|"];
106 [label="Function call: R|<local>/b|.R|kotlin/Boolean.not|()"];
107 [label="Exit block"];
}
108 [label="Exit when branch result"];
109 [label="Exit when"];
}
110 [label="Access variable R|<local>/b|"];
111 [label="Function call: R|<local>/b|.<Unresolved name: not>#()"];
subgraph cluster_24 {
color=blue
112 [label="Enter when"];
subgraph cluster_25 {
color=blue
113 [label="Enter when branch condition "];
114 [label="Access variable R|<local>/b|"];
115 [label="Type operator: (R|<local>/b| as? R|kotlin/Boolean|)"];
116 [label="Const: Null(null)"];
117 [label="Operator =="];
118 [label="Exit when branch condition"];
}
subgraph cluster_26 {
color=blue
119 [label="Enter when branch condition else"];
120 [label="Exit when branch condition"];
}
121 [label="Enter when branch result"];
subgraph cluster_27 {
color=blue
122 [label="Enter block"];
123 [label="Access variable R|<local>/b|"];
124 [label="Function call: R|<local>/b|.R|kotlin/Boolean.not|()"];
125 [label="Exit block"];
}
126 [label="Exit when branch result"];
127 [label="Enter when branch result"];
subgraph cluster_28 {
color=blue
128 [label="Enter block"];
129 [label="Access variable R|<local>/b|"];
130 [label="Function call: R|<local>/b|.<Unresolved name: not>#()"];
131 [label="Exit block"];
}
132 [label="Exit when branch result"];
133 [label="Exit when"];
}
134 [label="Access variable R|<local>/b|"];
135 [label="Function call: R|<local>/b|.<Unresolved name: not>#()"];
136 [label="Exit function test_4" style="filled" fillcolor=red];
}
87 -> {88};
88 -> {89};
89 -> {90};
90 -> {91};
91 -> {92};
92 -> {93};
93 -> {94};
94 -> {103 95};
95 -> {96};
96 -> {97};
97 -> {98};
98 -> {99};
99 -> {100};
100 -> {101};
101 -> {102};
102 -> {109};
103 -> {104};
104 -> {105};
105 -> {106};
106 -> {107};
107 -> {108};
108 -> {109};
109 -> {110};
110 -> {111};
111 -> {112};
112 -> {113};
113 -> {114};
114 -> {115};
115 -> {116};
116 -> {117};
117 -> {118};
118 -> {127 119};
119 -> {120};
120 -> {121};
121 -> {122};
122 -> {123};
123 -> {124};
124 -> {125};
125 -> {126};
126 -> {133};
127 -> {128};
128 -> {129};
129 -> {130};
130 -> {131};
131 -> {132};
132 -> {133};
133 -> {134};
134 -> {135};
135 -> {136};
}
@@ -0,0 +1,45 @@
// !DUMP_CFG
fun test_1(x: Any?) {
x as String
x.length
}
fun test_2(x: Any?) {
if (x as Boolean) {
x.not()
}
x.not()
}
fun test_3(b: Boolean, x: Any?) {
if (b && x as Boolean) {
x.not()
}
x.<!UNRESOLVED_REFERENCE!>not<!>()
if (b && x as Boolean == true) {
x.not()
}
x.<!UNRESOLVED_REFERENCE!>not<!>()
if (b || x as Boolean) {
x.<!UNRESOLVED_REFERENCE!>not<!>()
}
x.<!UNRESOLVED_REFERENCE!>not<!>()
}
fun test_4(b: Any) {
if (b as? Boolean != null) {
b.not()
} else {
b.<!UNRESOLVED_REFERENCE!>not<!>()
}
b.<!UNRESOLVED_REFERENCE!>not<!>()
if (b as? Boolean == null) {
b.<!UNRESOLVED_REFERENCE!>not<!>()
} else {
b.not()
}
b.<!UNRESOLVED_REFERENCE!>not<!>()
}
@@ -0,0 +1,59 @@
FILE: casts.kt
public final fun test_1(x: R|kotlin/Any?|): R|kotlin/Unit| {
(R|<local>/x| as R|kotlin/String|)
R|<local>/x|.R|kotlin/String.length|
}
public final fun test_2(x: R|kotlin/Any?|): R|kotlin/Unit| {
when () {
(R|<local>/x| as R|kotlin/Boolean|) -> {
R|<local>/x|.R|kotlin/Boolean.not|()
}
}
R|<local>/x|.R|kotlin/Boolean.not|()
}
public final fun test_3(b: R|kotlin/Boolean|, x: R|kotlin/Any?|): R|kotlin/Unit| {
when () {
R|<local>/b| && (R|<local>/x| as R|kotlin/Boolean|) -> {
R|<local>/x|.R|kotlin/Boolean.not|()
}
}
R|<local>/x|.<Unresolved name: not>#()
when () {
R|<local>/b| && ==((R|<local>/x| as R|kotlin/Boolean|), Boolean(true)) -> {
R|<local>/x|.R|kotlin/Boolean.not|()
}
}
R|<local>/x|.<Unresolved name: not>#()
when () {
R|<local>/b| || (R|<local>/x| as R|kotlin/Boolean|) -> {
R|<local>/x|.<Unresolved name: not>#()
}
}
R|<local>/x|.<Unresolved name: not>#()
}
public final fun test_4(b: R|kotlin/Any|): R|kotlin/Unit| {
when () {
!=((R|<local>/b| as? R|kotlin/Boolean|), Null(null)) -> {
R|<local>/b|.R|kotlin/Boolean.not|()
}
else -> {
R|<local>/b|.<Unresolved name: not>#()
}
}
R|<local>/b|.<Unresolved name: not>#()
when () {
==((R|<local>/b| as? R|kotlin/Boolean|), Null(null)) -> {
R|<local>/b|.<Unresolved name: not>#()
}
else -> {
R|<local>/b|.R|kotlin/Boolean.not|()
}
}
R|<local>/b|.<Unresolved name: not>#()
}
@@ -0,0 +1,285 @@
digraph elvis_kt {
graph [nodesep=3]
node [shape=box penwidth=2]
edge [penwidth=2]
subgraph cluster_0 {
color=red
0 [label="Enter function foo" style="filled" fillcolor=red];
1 [label="Exit function foo" style="filled" fillcolor=red];
}
0 -> {1};
subgraph cluster_1 {
color=red
2 [label="Enter function getter" style="filled" fillcolor=red];
3 [label="Exit function getter" style="filled" fillcolor=red];
}
2 -> {3};
subgraph cluster_2 {
color=red
4 [label="Enter property" style="filled" fillcolor=red];
5 [label="Exit property" style="filled" fillcolor=red];
}
4 -> {5};
subgraph cluster_3 {
color=red
6 [label="Enter function test_1" style="filled" fillcolor=red];
subgraph cluster_4 {
color=blue
7 [label="Enter when"];
subgraph cluster_5 {
color=blue
8 [label="Enter when branch condition "];
subgraph cluster_6 {
color=blue
9 [label="Enter when"];
10 [label="Access variable R|<local>/x|"];
11 [label="Enter safe call"];
12 [label="Access variable R|/A.b|"];
13 [label="Exit safe call"];
14 [label="Variable declaration: lval <elvis>: R|kotlin/Boolean?|"];
subgraph cluster_7 {
color=blue
15 [label="Enter when branch condition "];
16 [label="Const: Null(null)"];
17 [label="Operator =="];
18 [label="Exit when branch condition"];
}
subgraph cluster_8 {
color=blue
19 [label="Enter when branch condition else"];
20 [label="Exit when branch condition"];
}
21 [label="Enter when branch result"];
subgraph cluster_9 {
color=blue
22 [label="Enter block"];
23 [label="Access variable R|<local>/<elvis>|"];
24 [label="Exit block"];
}
25 [label="Exit when branch result"];
26 [label="Enter when branch result"];
subgraph cluster_10 {
color=blue
27 [label="Enter block"];
28 [label="Jump: ^test_1 Unit"];
29 [label="Stub" style="filled" fillcolor=gray];
30 [label="Exit block" style="filled" fillcolor=gray];
}
31 [label="Exit when branch result" style="filled" fillcolor=gray];
32 [label="Exit when"];
}
33 [label="Exit when branch condition"];
}
34 [label="Synthetic else branch"];
35 [label="Enter when branch result"];
subgraph cluster_11 {
color=blue
36 [label="Enter block"];
37 [label="Access variable R|<local>/x|"];
38 [label="Function call: R|<local>/x|.R|/A.foo|()"];
39 [label="Exit block"];
}
40 [label="Exit when branch result"];
41 [label="Exit when"];
}
42 [label="Exit function test_1" style="filled" fillcolor=red];
}
6 -> {7};
7 -> {8};
8 -> {9};
9 -> {10};
10 -> {11 13};
11 -> {12};
12 -> {13};
13 -> {14};
14 -> {15};
15 -> {16};
16 -> {17};
17 -> {18};
18 -> {26 19};
19 -> {20};
20 -> {21};
21 -> {22};
22 -> {23};
23 -> {24};
24 -> {25};
25 -> {32};
26 -> {27};
27 -> {28};
28 -> {42};
28 -> {29} [style=dotted];
29 -> {30} [style=dotted];
30 -> {31} [style=dotted];
31 -> {32} [style=dotted];
32 -> {33};
33 -> {35 34};
34 -> {41};
35 -> {36};
36 -> {37};
37 -> {38};
38 -> {39};
39 -> {40};
40 -> {41};
41 -> {42};
subgraph cluster_12 {
color=red
43 [label="Enter function test2" style="filled" fillcolor=red];
subgraph cluster_13 {
color=blue
44 [label="Enter when"];
subgraph cluster_14 {
color=blue
45 [label="Enter when branch condition "];
46 [label="Access variable R|<local>/b|"];
47 [label="Type operator: (R|<local>/b| !is R|kotlin/String|)"];
48 [label="Exit when branch condition"];
}
49 [label="Synthetic else branch"];
50 [label="Enter when branch result"];
subgraph cluster_15 {
color=blue
51 [label="Enter block"];
52 [label="Const: String()"];
53 [label="Jump: ^test2 String()"];
54 [label="Stub" style="filled" fillcolor=gray];
55 [label="Exit block" style="filled" fillcolor=gray];
}
56 [label="Exit when branch result" style="filled" fillcolor=gray];
57 [label="Exit when"];
}
subgraph cluster_16 {
color=blue
58 [label="Enter when"];
subgraph cluster_17 {
color=blue
59 [label="Enter when branch condition "];
60 [label="Access variable R|<local>/a|"];
61 [label="Type operator: (R|<local>/a| !is R|kotlin/String?|)"];
62 [label="Exit when branch condition"];
}
63 [label="Synthetic else branch"];
64 [label="Enter when branch result"];
subgraph cluster_18 {
color=blue
65 [label="Enter block"];
66 [label="Const: String()"];
67 [label="Jump: ^test2 String()"];
68 [label="Stub" style="filled" fillcolor=gray];
69 [label="Exit block" style="filled" fillcolor=gray];
}
70 [label="Exit when branch result" style="filled" fillcolor=gray];
71 [label="Exit when"];
}
subgraph cluster_19 {
color=blue
72 [label="Enter when"];
73 [label="Access variable R|<local>/a|"];
74 [label="Variable declaration: lval <elvis>: R|kotlin/String?|"];
subgraph cluster_20 {
color=blue
75 [label="Enter when branch condition "];
76 [label="Const: Null(null)"];
77 [label="Operator =="];
78 [label="Exit when branch condition"];
}
subgraph cluster_21 {
color=blue
79 [label="Enter when branch condition else"];
80 [label="Exit when branch condition"];
}
81 [label="Enter when branch result"];
subgraph cluster_22 {
color=blue
82 [label="Enter block"];
83 [label="Access variable R|<local>/<elvis>|"];
84 [label="Exit block"];
}
85 [label="Exit when branch result"];
86 [label="Enter when branch result"];
subgraph cluster_23 {
color=blue
87 [label="Enter block"];
88 [label="Access variable R|<local>/b|"];
89 [label="Exit block"];
}
90 [label="Exit when branch result"];
91 [label="Exit when"];
}
92 [label="Jump: ^test2 when (lval <elvis>: R|kotlin/String?| = R|<local>/a|) {
==($subj$, Null(null)) -> {
R|<local>/b|
}
else -> {
R|<local>/<elvis>|
}
}
"];
93 [label="Stub" style="filled" fillcolor=gray];
94 [label="Exit function test2" style="filled" fillcolor=red];
}
43 -> {44};
44 -> {45};
45 -> {46};
46 -> {47};
47 -> {48};
48 -> {50 49};
49 -> {57};
50 -> {51};
51 -> {52};
52 -> {53};
53 -> {94};
53 -> {54} [style=dotted];
54 -> {55} [style=dotted];
55 -> {56} [style=dotted];
56 -> {57} [style=dotted];
57 -> {58};
58 -> {59};
59 -> {60};
60 -> {61};
61 -> {62};
62 -> {64 63};
63 -> {71};
64 -> {65};
65 -> {66};
66 -> {67};
67 -> {94};
67 -> {68} [style=dotted];
68 -> {69} [style=dotted];
69 -> {70} [style=dotted];
70 -> {71} [style=dotted];
71 -> {72};
72 -> {73};
73 -> {74};
74 -> {75};
75 -> {76};
76 -> {77};
77 -> {78};
78 -> {86 79};
79 -> {80};
80 -> {81};
81 -> {82};
82 -> {83};
83 -> {84};
84 -> {85};
85 -> {91};
86 -> {87};
87 -> {88};
88 -> {89};
89 -> {90};
90 -> {91};
91 -> {92};
92 -> {94};
92 -> {93} [style=dotted];
93 -> {94} [style=dotted];
}
@@ -0,0 +1,17 @@
// !DUMP_CFG
interface A {
fun foo()
val b: Boolean
}
fun test_1(x: A?) {
if (x?.b ?: return) {
x.foo()
}
}
fun test2(a: Any?, b: Any?): String {
if (b !is String) return ""
if (a !is String?) return ""
return a ?: b
}
@@ -0,0 +1,47 @@
FILE: elvis.kt
public abstract interface A : R|kotlin/Any| {
public abstract fun foo(): R|kotlin/Unit|
public abstract val b: R|kotlin/Boolean|
public get(): R|kotlin/Boolean|
}
public final fun test_1(x: R|A?|): R|kotlin/Unit| {
when () {
when (lval <elvis>: R|kotlin/Boolean?| = R|<local>/x|?.R|/A.b|) {
==($subj$, Null(null)) -> {
^test_1 Unit
}
else -> {
R|<local>/<elvis>|
}
}
-> {
R|<local>/x|.R|/A.foo|()
}
}
}
public final fun test2(a: R|kotlin/Any?|, b: R|kotlin/Any?|): R|kotlin/String| {
when () {
(R|<local>/b| !is R|kotlin/String|) -> {
^test2 String()
}
}
when () {
(R|<local>/a| !is R|kotlin/String?|) -> {
^test2 String()
}
}
^test2 when (lval <elvis>: R|kotlin/String?| = R|<local>/a|) {
==($subj$, Null(null)) -> {
R|<local>/b|
}
else -> {
R|<local>/<elvis>|
}
}
}
@@ -0,0 +1,480 @@
digraph returns_kt {
graph [nodesep=3]
node [shape=box penwidth=2]
edge [penwidth=2]
subgraph cluster_0 {
color=red
0 [label="Enter function test_0" style="filled" fillcolor=red];
subgraph cluster_1 {
color=blue
1 [label="Enter when"];
subgraph cluster_2 {
color=blue
2 [label="Enter when branch condition "];
3 [label="Access variable R|<local>/x|"];
4 [label="Type operator: (R|<local>/x| is R|kotlin/String|)"];
5 [label="Exit when branch condition"];
}
subgraph cluster_3 {
color=blue
6 [label="Enter when branch condition else"];
7 [label="Exit when branch condition"];
}
8 [label="Enter when branch result"];
subgraph cluster_4 {
color=blue
9 [label="Enter block"];
10 [label="Exit block"];
}
11 [label="Exit when branch result"];
12 [label="Enter when branch result"];
subgraph cluster_5 {
color=blue
13 [label="Enter block"];
14 [label="Access variable R|<local>/x|"];
15 [label="Access variable R|kotlin/String.length|"];
16 [label="Exit block"];
}
17 [label="Exit when branch result"];
18 [label="Exit when"];
}
19 [label="Access variable R|<local>/x|"];
20 [label="Access variable <Unresolved name: length>#"];
21 [label="Exit function test_0" style="filled" fillcolor=red];
}
0 -> {1};
1 -> {2};
2 -> {3};
3 -> {4};
4 -> {5};
5 -> {12 6};
6 -> {7};
7 -> {8};
8 -> {9};
9 -> {10};
10 -> {11};
11 -> {18};
12 -> {13};
13 -> {14};
14 -> {15};
15 -> {16};
16 -> {17};
17 -> {18};
18 -> {19};
19 -> {20};
20 -> {21};
subgraph cluster_6 {
color=red
22 [label="Enter function test_1" style="filled" fillcolor=red];
subgraph cluster_7 {
color=blue
23 [label="Enter when"];
subgraph cluster_8 {
color=blue
24 [label="Enter when branch condition "];
25 [label="Access variable R|<local>/x|"];
26 [label="Type operator: (R|<local>/x| is R|kotlin/String|)"];
27 [label="Exit when branch condition"];
}
subgraph cluster_9 {
color=blue
28 [label="Enter when branch condition else"];
29 [label="Exit when branch condition"];
}
30 [label="Enter when branch result"];
subgraph cluster_10 {
color=blue
31 [label="Enter block"];
32 [label="Jump: ^test_1 Unit"];
33 [label="Stub" style="filled" fillcolor=gray];
34 [label="Exit block" style="filled" fillcolor=gray];
}
35 [label="Exit when branch result" style="filled" fillcolor=gray];
36 [label="Enter when branch result"];
subgraph cluster_11 {
color=blue
37 [label="Enter block"];
38 [label="Access variable R|<local>/x|"];
39 [label="Access variable R|kotlin/String.length|"];
40 [label="Exit block"];
}
41 [label="Exit when branch result"];
42 [label="Exit when"];
}
43 [label="Access variable R|<local>/x|"];
44 [label="Access variable R|kotlin/String.length|"];
45 [label="Exit function test_1" style="filled" fillcolor=red];
}
22 -> {23};
23 -> {24};
24 -> {25};
25 -> {26};
26 -> {27};
27 -> {36 28};
28 -> {29};
29 -> {30};
30 -> {31};
31 -> {32};
32 -> {45};
32 -> {33} [style=dotted];
33 -> {34} [style=dotted];
34 -> {35} [style=dotted];
35 -> {42} [style=dotted];
36 -> {37};
37 -> {38};
38 -> {39};
39 -> {40};
40 -> {41};
41 -> {42};
42 -> {43};
43 -> {44};
44 -> {45};
subgraph cluster_12 {
color=red
46 [label="Enter function foo" style="filled" fillcolor=red];
47 [label="Exit function foo" style="filled" fillcolor=red];
}
46 -> {47};
subgraph cluster_13 {
color=red
48 [label="Enter function bar" style="filled" fillcolor=red];
49 [label="Exit function bar" style="filled" fillcolor=red];
}
48 -> {49};
subgraph cluster_14 {
color=red
50 [label="Enter function baz" style="filled" fillcolor=red];
51 [label="Exit function baz" style="filled" fillcolor=red];
}
50 -> {51};
subgraph cluster_15 {
color=red
52 [label="Enter function test_2" style="filled" fillcolor=red];
subgraph cluster_16 {
color=blue
53 [label="Enter when"];
subgraph cluster_17 {
color=blue
54 [label="Enter when branch condition "];
55 [label="Access variable R|<local>/x|"];
56 [label="Type operator: (R|<local>/x| is R|B|)"];
57 [label="Exit when branch condition"];
}
subgraph cluster_18 {
color=blue
58 [label="Enter when branch condition "];
59 [label="Access variable R|<local>/x|"];
60 [label="Type operator: (R|<local>/x| is R|C|)"];
61 [label="Exit when branch condition"];
}
subgraph cluster_19 {
color=blue
62 [label="Enter when branch condition else"];
63 [label="Exit when branch condition"];
}
64 [label="Enter when branch result"];
subgraph cluster_20 {
color=blue
65 [label="Enter block"];
66 [label="Jump: ^test_2 Unit"];
67 [label="Stub" style="filled" fillcolor=gray];
68 [label="Exit block" style="filled" fillcolor=gray];
}
69 [label="Exit when branch result" style="filled" fillcolor=gray];
70 [label="Enter when branch result"];
subgraph cluster_21 {
color=blue
71 [label="Enter block"];
72 [label="Access variable R|<local>/x|"];
73 [label="Function call: R|<local>/x|.R|/C.baz|()"];
74 [label="Exit block"];
}
75 [label="Exit when branch result"];
76 [label="Enter when branch result"];
subgraph cluster_22 {
color=blue
77 [label="Enter block"];
78 [label="Access variable R|<local>/x|"];
79 [label="Function call: R|<local>/x|.R|/B.bar|()"];
80 [label="Exit block"];
}
81 [label="Exit when branch result"];
82 [label="Exit when"];
}
83 [label="Access variable R|<local>/x|"];
84 [label="Function call: R|<local>/x|.R|/A.foo|()"];
85 [label="Access variable R|<local>/x|"];
86 [label="Function call: R|<local>/x|.<Unresolved name: bar>#()"];
87 [label="Access variable R|<local>/x|"];
88 [label="Function call: R|<local>/x|.<Unresolved name: baz>#()"];
89 [label="Exit function test_2" style="filled" fillcolor=red];
}
52 -> {53};
53 -> {54};
54 -> {55};
55 -> {56};
56 -> {57};
57 -> {76 58};
58 -> {59};
59 -> {60};
60 -> {61};
61 -> {70 62};
62 -> {63};
63 -> {64};
64 -> {65};
65 -> {66};
66 -> {89};
66 -> {67} [style=dotted];
67 -> {68} [style=dotted];
68 -> {69} [style=dotted];
69 -> {82} [style=dotted];
70 -> {71};
71 -> {72};
72 -> {73};
73 -> {74};
74 -> {75};
75 -> {82};
76 -> {77};
77 -> {78};
78 -> {79};
79 -> {80};
80 -> {81};
81 -> {82};
82 -> {83};
83 -> {84};
84 -> {85};
85 -> {86};
86 -> {87};
87 -> {88};
88 -> {89};
subgraph cluster_23 {
color=red
90 [label="Enter function test_3" style="filled" fillcolor=red];
subgraph cluster_24 {
color=blue
91 [label="Enter when"];
subgraph cluster_25 {
color=blue
92 [label="Enter when branch condition "];
93 [label="Access variable R|<local>/x|"];
94 [label="Type operator: (R|<local>/x| is R|B|)"];
95 [label="Exit when branch condition"];
}
subgraph cluster_26 {
color=blue
96 [label="Enter when branch condition "];
97 [label="Access variable R|<local>/x|"];
98 [label="Type operator: (R|<local>/x| is R|C|)"];
99 [label="Exit when branch condition"];
}
100 [label="Synthetic else branch"];
101 [label="Enter when branch result"];
subgraph cluster_27 {
color=blue
102 [label="Enter block"];
103 [label="Access variable R|<local>/x|"];
104 [label="Function call: R|<local>/x|.R|/C.baz|()"];
105 [label="Exit block"];
}
106 [label="Exit when branch result"];
107 [label="Enter when branch result"];
subgraph cluster_28 {
color=blue
108 [label="Enter block"];
109 [label="Access variable R|<local>/x|"];
110 [label="Function call: R|<local>/x|.R|/B.bar|()"];
111 [label="Exit block"];
}
112 [label="Exit when branch result"];
113 [label="Exit when"];
}
114 [label="Access variable R|<local>/x|"];
115 [label="Function call: R|<local>/x|.<Unresolved name: foo>#()"];
116 [label="Access variable R|<local>/x|"];
117 [label="Function call: R|<local>/x|.<Unresolved name: bar>#()"];
118 [label="Access variable R|<local>/x|"];
119 [label="Function call: R|<local>/x|.<Unresolved name: baz>#()"];
120 [label="Exit function test_3" style="filled" fillcolor=red];
}
90 -> {91};
91 -> {92};
92 -> {93};
93 -> {94};
94 -> {95};
95 -> {107 96};
96 -> {97};
97 -> {98};
98 -> {99};
99 -> {101 100};
100 -> {113};
101 -> {102};
102 -> {103};
103 -> {104};
104 -> {105};
105 -> {106};
106 -> {113};
107 -> {108};
108 -> {109};
109 -> {110};
110 -> {111};
111 -> {112};
112 -> {113};
113 -> {114};
114 -> {115};
115 -> {116};
116 -> {117};
117 -> {118};
118 -> {119};
119 -> {120};
subgraph cluster_29 {
color=red
121 [label="Enter function runHigherOrder" style="filled" fillcolor=red];
122 [label="Function call: R|<local>/f|.R|FakeOverride<kotlin/Function0.invoke: R|T|>|()"];
123 [label="Jump: ^runHigherOrder R|<local>/f|.R|FakeOverride<kotlin/Function0.invoke: R|T|>|()"];
124 [label="Stub" style="filled" fillcolor=gray];
125 [label="Exit function runHigherOrder" style="filled" fillcolor=red];
}
121 -> {122};
122 -> {123};
123 -> {125};
123 -> {124} [style=dotted];
124 -> {125} [style=dotted];
subgraph cluster_30 {
color=red
126 [label="Enter function getter" style="filled" fillcolor=red];
127 [label="Access variable R|kotlin/String.length|"];
128 [label="Jump: ^ this@R|/ext|.R|kotlin/String.length|"];
129 [label="Stub" style="filled" fillcolor=gray];
130 [label="Exit function getter" style="filled" fillcolor=red];
}
126 -> {127};
127 -> {128};
128 -> {130};
128 -> {129} [style=dotted];
129 -> {130} [style=dotted];
subgraph cluster_31 {
color=red
131 [label="Enter property" style="filled" fillcolor=red];
132 [label="Exit property" style="filled" fillcolor=red];
}
131 -> {132};
subgraph cluster_32 {
color=red
133 [label="Enter function test_4" style="filled" fillcolor=red];
134 [label="Access variable R|<local>/a|"];
135 [label="Type operator: (R|<local>/a| as? R|kotlin/String|)"];
136 [label="Variable declaration: lval s: R|kotlin/String?|"];
subgraph cluster_33 {
color=blue
137 [label="Enter when"];
138 [label="Access variable R|<local>/s|"];
139 [label="Enter safe call"];
140 [label="Access variable R|/ext|"];
141 [label="Exit safe call"];
142 [label="Variable declaration: lval <elvis>: R|kotlin/Int?|"];
subgraph cluster_34 {
color=blue
143 [label="Enter when branch condition "];
144 [label="Const: Null(null)"];
145 [label="Operator =="];
146 [label="Exit when branch condition"];
}
subgraph cluster_35 {
color=blue
147 [label="Enter when branch condition else"];
148 [label="Exit when branch condition"];
}
149 [label="Enter when branch result"];
subgraph cluster_36 {
color=blue
150 [label="Enter block"];
151 [label="Access variable R|<local>/<elvis>|"];
152 [label="Exit block"];
}
153 [label="Exit when branch result"];
154 [label="Enter when branch result"];
subgraph cluster_37 {
color=blue
155 [label="Enter block"];
156 [label="Jump: ^test_4 Unit"];
157 [label="Stub" style="filled" fillcolor=gray];
158 [label="Exit block" style="filled" fillcolor=gray];
}
159 [label="Exit when branch result" style="filled" fillcolor=gray];
160 [label="Exit when"];
}
161 [label="Variable declaration: lval length: R|kotlin/Int|"];
162 [label="Postponed enter to lambda"];
163 [label="Postponed exit from lambda"];
164 [label="Function call: R|/runHigherOrder|<R|kotlin/Int|>(...)"];
165 [label="Exit function test_4" style="filled" fillcolor=red];
}
133 -> {134};
134 -> {135};
135 -> {136};
136 -> {137};
137 -> {138};
138 -> {139 141};
139 -> {140};
140 -> {141};
141 -> {142};
142 -> {143};
143 -> {144};
144 -> {145};
145 -> {146};
146 -> {154 147};
147 -> {148};
148 -> {149};
149 -> {150};
150 -> {151};
151 -> {152};
152 -> {153};
153 -> {160};
154 -> {155};
155 -> {156};
156 -> {165};
156 -> {157} [style=dotted];
157 -> {158} [style=dotted];
158 -> {159} [style=dotted];
159 -> {160} [style=dotted];
160 -> {161};
161 -> {162};
162 -> {163 163} [color=green];
163 -> {164};
164 -> {165};
subgraph cluster_38 {
color=red
166 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
167 [label="Access variable R|<local>/s|"];
168 [label="Access variable R|kotlin/String.length|"];
169 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
166 -> {167};
167 -> {168};
168 -> {169};
}
@@ -0,0 +1,63 @@
// !DUMP_CFG
fun test_0(x: Any) {
if (x is String) {
x.length
} else {
}
x.<!UNRESOLVED_REFERENCE!>length<!>
}
fun test_1(x: Any) {
if (x is String) {
x.length
} else {
return
}
x.length
}
interface A {
fun foo()
}
interface B : A {
fun bar()
}
interface C : A {
fun baz()
}
fun test_2(x: Any) {
when {
x is B -> x.bar()
x is C -> x.baz()
else -> return
}
x.foo()
x.<!UNRESOLVED_REFERENCE!>bar<!>()
x.<!UNRESOLVED_REFERENCE!>baz<!>()
}
fun test_3(x: Any) {
when {
x is B -> x.bar()
x is C -> x.baz()
}
x.<!UNRESOLVED_REFERENCE!>foo<!>()
x.<!UNRESOLVED_REFERENCE!>bar<!>()
x.<!UNRESOLVED_REFERENCE!>baz<!>()
}
fun <T> runHigherOrder(f: () -> T): T = f()
val String.ext: Int get() = length
fun test_4(a: Any?) {
val s = a as? String
val length = s?.ext ?: return
runHigherOrder {
s.length // Should be OK
}
}
@@ -0,0 +1,90 @@
FILE: returns.kt
public final fun test_0(x: R|kotlin/Any|): R|kotlin/Unit| {
when () {
(R|<local>/x| is R|kotlin/String|) -> {
R|<local>/x|.R|kotlin/String.length|
}
else -> {
}
}
R|<local>/x|.<Unresolved name: length>#
}
public final fun test_1(x: R|kotlin/Any|): R|kotlin/Unit| {
when () {
(R|<local>/x| is R|kotlin/String|) -> {
R|<local>/x|.R|kotlin/String.length|
}
else -> {
^test_1 Unit
}
}
R|<local>/x|.R|kotlin/String.length|
}
public abstract interface A : R|kotlin/Any| {
public abstract fun foo(): R|kotlin/Unit|
}
public abstract interface B : R|A| {
public abstract fun bar(): R|kotlin/Unit|
}
public abstract interface C : R|A| {
public abstract fun baz(): R|kotlin/Unit|
}
public final fun test_2(x: R|kotlin/Any|): R|kotlin/Unit| {
when () {
(R|<local>/x| is R|B|) -> {
R|<local>/x|.R|/B.bar|()
}
(R|<local>/x| is R|C|) -> {
R|<local>/x|.R|/C.baz|()
}
else -> {
^test_2 Unit
}
}
R|<local>/x|.R|/A.foo|()
R|<local>/x|.<Unresolved name: bar>#()
R|<local>/x|.<Unresolved name: baz>#()
}
public final fun test_3(x: R|kotlin/Any|): R|kotlin/Unit| {
when () {
(R|<local>/x| is R|B|) -> {
R|<local>/x|.R|/B.bar|()
}
(R|<local>/x| is R|C|) -> {
R|<local>/x|.R|/C.baz|()
}
}
R|<local>/x|.<Unresolved name: foo>#()
R|<local>/x|.<Unresolved name: bar>#()
R|<local>/x|.<Unresolved name: baz>#()
}
public final fun <T> runHigherOrder(f: R|() -> T|): R|T| {
^runHigherOrder R|<local>/f|.R|FakeOverride<kotlin/Function0.invoke: R|T|>|()
}
public final val R|kotlin/String|.ext: R|kotlin/Int|
public get(): R|kotlin/Int| {
^ this@R|/ext|.R|kotlin/String.length|
}
public final fun test_4(a: R|kotlin/Any?|): R|kotlin/Unit| {
lval s: R|kotlin/String?| = (R|<local>/a| as? R|kotlin/String|)
lval length: R|kotlin/Int| = when (lval <elvis>: R|kotlin/Int?| = R|<local>/s|?.R|/ext|) {
==($subj$, Null(null)) -> {
^test_4 Unit
}
else -> {
R|<local>/<elvis>|
}
}
R|/runHigherOrder|<R|kotlin/Int|>(<L> = runHigherOrder@fun <anonymous>(): R|kotlin/Int| {
^ R|<local>/s|.R|kotlin/String.length|
}
)
}
@@ -0,0 +1,189 @@
digraph simpleIf_kt {
graph [nodesep=3]
node [shape=box penwidth=2]
edge [penwidth=2]
subgraph cluster_0 {
color=red
0 [label="Enter function test_1" style="filled" fillcolor=red];
subgraph cluster_1 {
color=blue
1 [label="Enter when"];
subgraph cluster_2 {
color=blue
2 [label="Enter when branch condition "];
3 [label="Access variable R|<local>/x|"];
4 [label="Type operator: (R|<local>/x| is R|kotlin/String|)"];
5 [label="Exit when branch condition"];
}
6 [label="Synthetic else branch"];
7 [label="Enter when branch result"];
subgraph cluster_3 {
color=blue
8 [label="Enter block"];
9 [label="Access variable R|<local>/x|"];
10 [label="Access variable R|kotlin/String.length|"];
11 [label="Exit block"];
}
12 [label="Exit when branch result"];
13 [label="Exit when"];
}
14 [label="Access variable R|<local>/x|"];
15 [label="Access variable <Unresolved name: length>#"];
16 [label="Exit function test_1" style="filled" fillcolor=red];
}
0 -> {1};
1 -> {2};
2 -> {3};
3 -> {4};
4 -> {5};
5 -> {7 6};
6 -> {13};
7 -> {8};
8 -> {9};
9 -> {10};
10 -> {11};
11 -> {12};
12 -> {13};
13 -> {14};
14 -> {15};
15 -> {16};
subgraph cluster_4 {
color=red
17 [label="Enter function test_2" style="filled" fillcolor=red];
18 [label="Access variable R|<local>/x|"];
19 [label="Type operator: (R|<local>/x| is R|kotlin/String|)"];
20 [label="Variable declaration: lval b: R|kotlin/Boolean|"];
subgraph cluster_5 {
color=blue
21 [label="Enter when"];
subgraph cluster_6 {
color=blue
22 [label="Enter when branch condition "];
23 [label="Access variable R|<local>/b|"];
24 [label="Exit when branch condition"];
}
25 [label="Synthetic else branch"];
26 [label="Enter when branch result"];
subgraph cluster_7 {
color=blue
27 [label="Enter block"];
28 [label="Access variable R|<local>/x|"];
29 [label="Access variable R|kotlin/String.length|"];
30 [label="Exit block"];
}
31 [label="Exit when branch result"];
32 [label="Exit when"];
}
33 [label="Access variable R|<local>/x|"];
34 [label="Access variable <Unresolved name: length>#"];
35 [label="Exit function test_2" style="filled" fillcolor=red];
}
17 -> {18};
18 -> {19};
19 -> {20};
20 -> {21};
21 -> {22};
22 -> {23};
23 -> {24};
24 -> {26 25};
25 -> {32};
26 -> {27};
27 -> {28};
28 -> {29};
29 -> {30};
30 -> {31};
31 -> {32};
32 -> {33};
33 -> {34};
34 -> {35};
subgraph cluster_8 {
color=red
36 [label="Enter function test_3" style="filled" fillcolor=red];
subgraph cluster_9 {
color=blue
37 [label="Enter when"];
subgraph cluster_10 {
color=blue
38 [label="Enter when branch condition "];
39 [label="Access variable R|<local>/x|"];
40 [label="Type operator: (R|<local>/x| !is R|kotlin/String|)"];
41 [label="Exit when branch condition"];
}
subgraph cluster_11 {
color=blue
42 [label="Enter when branch condition "];
43 [label="Access variable R|<local>/x|"];
44 [label="Type operator: (R|<local>/x| !is R|kotlin/Int|)"];
45 [label="Exit when branch condition"];
}
subgraph cluster_12 {
color=blue
46 [label="Enter when branch condition else"];
47 [label="Exit when branch condition"];
}
48 [label="Enter when branch result"];
subgraph cluster_13 {
color=blue
49 [label="Enter block"];
50 [label="Access variable R|<local>/x|"];
51 [label="Access variable R|kotlin/String.length|"];
52 [label="Access variable R|<local>/x|"];
53 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()"];
54 [label="Exit block"];
}
55 [label="Exit when branch result"];
56 [label="Enter when branch result"];
subgraph cluster_14 {
color=blue
57 [label="Enter block"];
58 [label="Exit block"];
}
59 [label="Exit when branch result"];
60 [label="Enter when branch result"];
subgraph cluster_15 {
color=blue
61 [label="Enter block"];
62 [label="Exit block"];
}
63 [label="Exit when branch result"];
64 [label="Exit when"];
}
65 [label="Exit function test_3" style="filled" fillcolor=red];
}
36 -> {37};
37 -> {38};
38 -> {39};
39 -> {40};
40 -> {41};
41 -> {60 42};
42 -> {43};
43 -> {44};
44 -> {45};
45 -> {56 46};
46 -> {47};
47 -> {48};
48 -> {49};
49 -> {50};
50 -> {51};
51 -> {52};
52 -> {53};
53 -> {54};
54 -> {55};
55 -> {64};
56 -> {57};
57 -> {58};
58 -> {59};
59 -> {64};
60 -> {61};
61 -> {62};
62 -> {63};
63 -> {64};
64 -> {65};
}
@@ -0,0 +1,26 @@
// !DUMP_CFG
fun test_1(x: Any) {
if (x is String) {
x.length
}
x.<!UNRESOLVED_REFERENCE!>length<!>
}
fun test_2(x: Any) {
val b = x is String
if (b) {
x.length
}
x.<!UNRESOLVED_REFERENCE!>length<!>
}
fun test_3(x: Any) {
when {
x !is String -> {}
x !is Int -> {}
else -> {
x.length
x.inc()
}
}
}
@@ -0,0 +1,33 @@
FILE: simpleIf.kt
public final fun test_1(x: R|kotlin/Any|): R|kotlin/Unit| {
when () {
(R|<local>/x| is R|kotlin/String|) -> {
R|<local>/x|.R|kotlin/String.length|
}
}
R|<local>/x|.<Unresolved name: length>#
}
public final fun test_2(x: R|kotlin/Any|): R|kotlin/Unit| {
lval b: R|kotlin/Boolean| = (R|<local>/x| is R|kotlin/String|)
when () {
R|<local>/b| -> {
R|<local>/x|.R|kotlin/String.length|
}
}
R|<local>/x|.<Unresolved name: length>#
}
public final fun test_3(x: R|kotlin/Any|): R|kotlin/Unit| {
when () {
(R|<local>/x| !is R|kotlin/String|) -> {
}
(R|<local>/x| !is R|kotlin/Int|) -> {
}
else -> {
R|<local>/x|.R|kotlin/String.length|
R|<local>/x|.R|kotlin/Int.inc|()
}
}
}
@@ -0,0 +1,130 @@
digraph smartcastFromArgument_kt {
graph [nodesep=3]
node [shape=box penwidth=2]
edge [penwidth=2]
subgraph cluster_0 {
color=red
0 [label="Enter function foo" style="filled" fillcolor=red];
1 [label="Exit function foo" style="filled" fillcolor=red];
}
0 -> {1};
subgraph cluster_1 {
color=red
2 [label="Enter function takeA" style="filled" fillcolor=red];
3 [label="Const: Boolean(true)"];
4 [label="Jump: ^takeA Boolean(true)"];
5 [label="Stub" style="filled" fillcolor=gray];
6 [label="Exit function takeA" style="filled" fillcolor=red];
}
2 -> {3};
3 -> {4};
4 -> {6};
4 -> {5} [style=dotted];
5 -> {6} [style=dotted];
subgraph cluster_2 {
color=red
7 [label="Enter function test" style="filled" fillcolor=red];
subgraph cluster_3 {
color=blue
8 [label="Enter when"];
subgraph cluster_4 {
color=blue
9 [label="Enter when branch condition "];
subgraph cluster_5 {
color=blue
10 [label="Enter when"];
11 [label="Access variable R|<local>/a|"];
12 [label="Type operator: (R|<local>/a| as? R|A|)"];
13 [label="Variable declaration: lval <elvis>: R|A?|"];
subgraph cluster_6 {
color=blue
14 [label="Enter when branch condition "];
15 [label="Const: Null(null)"];
16 [label="Operator =="];
17 [label="Exit when branch condition"];
}
subgraph cluster_7 {
color=blue
18 [label="Enter when branch condition else"];
19 [label="Exit when branch condition"];
}
20 [label="Enter when branch result"];
subgraph cluster_8 {
color=blue
21 [label="Enter block"];
22 [label="Access variable R|<local>/<elvis>|"];
23 [label="Exit block"];
}
24 [label="Exit when branch result"];
25 [label="Enter when branch result"];
subgraph cluster_9 {
color=blue
26 [label="Enter block"];
27 [label="Jump: ^test Unit"];
28 [label="Stub" style="filled" fillcolor=gray];
29 [label="Exit block" style="filled" fillcolor=gray];
}
30 [label="Exit when branch result" style="filled" fillcolor=gray];
31 [label="Exit when"];
}
32 [label="Function call: R|/takeA|(...)"];
33 [label="Exit when branch condition"];
}
34 [label="Synthetic else branch"];
35 [label="Enter when branch result"];
subgraph cluster_10 {
color=blue
36 [label="Enter block"];
37 [label="Access variable R|<local>/a|"];
38 [label="Function call: R|<local>/a|.R|/A.foo|()"];
39 [label="Exit block"];
}
40 [label="Exit when branch result"];
41 [label="Exit when"];
}
42 [label="Exit function test" style="filled" fillcolor=red];
}
7 -> {8};
8 -> {9};
9 -> {10};
10 -> {11};
11 -> {12};
12 -> {13};
13 -> {14};
14 -> {15};
15 -> {16};
16 -> {17};
17 -> {25 18};
18 -> {19};
19 -> {20};
20 -> {21};
21 -> {22};
22 -> {23};
23 -> {24};
24 -> {31};
25 -> {26};
26 -> {27};
27 -> {42};
27 -> {28} [style=dotted];
28 -> {29} [style=dotted];
29 -> {30} [style=dotted];
30 -> {31} [style=dotted];
31 -> {32};
32 -> {33};
33 -> {35 34};
34 -> {41};
35 -> {36};
36 -> {37};
37 -> {38};
38 -> {39};
39 -> {40};
40 -> {41};
41 -> {42};
}
@@ -0,0 +1,12 @@
// !DUMP_CFG
interface A {
fun foo()
}
fun takeA(a: A): Boolean = true
fun test(a: Any) {
if (takeA(a as? A ?: return)) {
a.foo()
}
}
@@ -0,0 +1,24 @@
FILE: smartcastFromArgument.kt
public abstract interface A : R|kotlin/Any| {
public abstract fun foo(): R|kotlin/Unit|
}
public final fun takeA(a: R|A|): R|kotlin/Boolean| {
^takeA Boolean(true)
}
public final fun test(a: R|kotlin/Any|): R|kotlin/Unit| {
when () {
R|/takeA|(when (lval <elvis>: R|A?| = (R|<local>/a| as? R|A|)) {
==($subj$, Null(null)) -> {
^test Unit
}
else -> {
R|<local>/<elvis>|
}
}
) -> {
R|<local>/a|.R|/A.foo|()
}
}
}
@@ -0,0 +1,649 @@
digraph when_kt {
graph [nodesep=3]
node [shape=box penwidth=2]
edge [penwidth=2]
subgraph cluster_0 {
color=red
0 [label="Enter function foo" style="filled" fillcolor=red];
1 [label="Exit function foo" style="filled" fillcolor=red];
}
0 -> {1};
subgraph cluster_1 {
color=red
2 [label="Enter function bar" style="filled" fillcolor=red];
3 [label="Exit function bar" style="filled" fillcolor=red];
}
2 -> {3};
subgraph cluster_2 {
color=red
4 [label="Enter function test_1" style="filled" fillcolor=red];
subgraph cluster_3 {
color=blue
5 [label="Enter when"];
subgraph cluster_4 {
color=blue
6 [label="Enter when branch condition "];
7 [label="Access variable R|<local>/x|"];
8 [label="Type operator: (R|<local>/x| is R|A|)"];
9 [label="Exit when branch condition"];
}
subgraph cluster_5 {
color=blue
10 [label="Enter when branch condition "];
11 [label="Access variable R|<local>/x|"];
12 [label="Type operator: (R|<local>/x| is R|B|)"];
13 [label="Exit when branch condition"];
}
14 [label="Synthetic else branch"];
15 [label="Enter when branch result"];
subgraph cluster_6 {
color=blue
16 [label="Enter block"];
17 [label="Access variable R|<local>/x|"];
18 [label="Function call: R|<local>/x|.R|/B.bar|()"];
19 [label="Exit block"];
}
20 [label="Exit when branch result"];
21 [label="Enter when branch result"];
subgraph cluster_7 {
color=blue
22 [label="Enter block"];
23 [label="Access variable R|<local>/x|"];
24 [label="Function call: R|<local>/x|.R|/A.foo|()"];
25 [label="Exit block"];
}
26 [label="Exit when branch result"];
27 [label="Exit when"];
}
subgraph cluster_8 {
color=blue
28 [label="Enter when"];
subgraph cluster_9 {
color=blue
29 [label="Enter when branch condition "];
30 [label="Access variable R|<local>/x|"];
31 [label="Type operator: (R|<local>/x| !is R|A|)"];
32 [label="Exit when branch condition"];
}
subgraph cluster_10 {
color=blue
33 [label="Enter when branch condition "];
34 [label="Access variable R|<local>/x|"];
35 [label="Type operator: (R|<local>/x| !is R|B|)"];
36 [label="Exit when branch condition"];
}
subgraph cluster_11 {
color=blue
37 [label="Enter when branch condition "];
38 [label="Access variable R|<local>/x|"];
39 [label="Type operator: (R|<local>/x| is R|kotlin/Int|)"];
40 [label="Exit when branch condition"];
}
subgraph cluster_12 {
color=blue
41 [label="Enter when branch condition else"];
42 [label="Exit when branch condition"];
}
43 [label="Enter when branch result"];
subgraph cluster_13 {
color=blue
44 [label="Enter block"];
45 [label="Access variable R|<local>/x|"];
46 [label="Function call: R|<local>/x|.R|/A.foo|()"];
47 [label="Access variable R|<local>/x|"];
48 [label="Function call: R|<local>/x|.R|/B.bar|()"];
49 [label="Exit block"];
}
50 [label="Exit when branch result"];
51 [label="Enter when branch result"];
subgraph cluster_14 {
color=blue
52 [label="Enter block"];
53 [label="Access variable R|<local>/x|"];
54 [label="Function call: R|<local>/x|.R|/A.foo|()"];
55 [label="Access variable R|<local>/x|"];
56 [label="Function call: R|<local>/x|.R|/B.bar|()"];
57 [label="Access variable R|<local>/x|"];
58 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()"];
59 [label="Exit block"];
}
60 [label="Exit when branch result"];
61 [label="Enter when branch result"];
subgraph cluster_15 {
color=blue
62 [label="Enter block"];
63 [label="Access variable R|<local>/x|"];
64 [label="Function call: R|<local>/x|.R|/A.foo|()"];
65 [label="Exit block"];
}
66 [label="Exit when branch result"];
67 [label="Enter when branch result"];
subgraph cluster_16 {
color=blue
68 [label="Enter block"];
69 [label="Exit block"];
}
70 [label="Exit when branch result"];
71 [label="Exit when"];
}
72 [label="Exit function test_1" style="filled" fillcolor=red];
}
4 -> {5};
5 -> {6};
6 -> {7};
7 -> {8};
8 -> {9};
9 -> {21 10};
10 -> {11};
11 -> {12};
12 -> {13};
13 -> {15 14};
14 -> {27};
15 -> {16};
16 -> {17};
17 -> {18};
18 -> {19};
19 -> {20};
20 -> {27};
21 -> {22};
22 -> {23};
23 -> {24};
24 -> {25};
25 -> {26};
26 -> {27};
27 -> {28};
28 -> {29};
29 -> {30};
30 -> {31};
31 -> {32};
32 -> {67 33};
33 -> {34};
34 -> {35};
35 -> {36};
36 -> {61 37};
37 -> {38};
38 -> {39};
39 -> {40};
40 -> {51 41};
41 -> {42};
42 -> {43};
43 -> {44};
44 -> {45};
45 -> {46};
46 -> {47};
47 -> {48};
48 -> {49};
49 -> {50};
50 -> {71};
51 -> {52};
52 -> {53};
53 -> {54};
54 -> {55};
55 -> {56};
56 -> {57};
57 -> {58};
58 -> {59};
59 -> {60};
60 -> {71};
61 -> {62};
62 -> {63};
63 -> {64};
64 -> {65};
65 -> {66};
66 -> {71};
67 -> {68};
68 -> {69};
69 -> {70};
70 -> {71};
71 -> {72};
subgraph cluster_17 {
color=red
73 [label="Enter function test_2" style="filled" fillcolor=red];
subgraph cluster_18 {
color=blue
74 [label="Enter when"];
75 [label="Access variable R|<local>/x|"];
subgraph cluster_19 {
color=blue
76 [label="Enter when branch condition "];
77 [label="Type operator: ($subj$ is R|A|)"];
78 [label="Exit when branch condition"];
}
subgraph cluster_20 {
color=blue
79 [label="Enter when branch condition "];
80 [label="Type operator: ($subj$ is R|B|)"];
81 [label="Exit when branch condition"];
}
82 [label="Synthetic else branch"];
83 [label="Enter when branch result"];
subgraph cluster_21 {
color=blue
84 [label="Enter block"];
85 [label="Access variable R|<local>/x|"];
86 [label="Function call: R|<local>/x|.R|/B.bar|()"];
87 [label="Exit block"];
}
88 [label="Exit when branch result"];
89 [label="Enter when branch result"];
subgraph cluster_22 {
color=blue
90 [label="Enter block"];
91 [label="Access variable R|<local>/x|"];
92 [label="Function call: R|<local>/x|.R|/A.foo|()"];
93 [label="Exit block"];
}
94 [label="Exit when branch result"];
95 [label="Exit when"];
}
subgraph cluster_23 {
color=blue
96 [label="Enter when"];
97 [label="Access variable R|<local>/x|"];
subgraph cluster_24 {
color=blue
98 [label="Enter when branch condition "];
99 [label="Type operator: ($subj$ !is R|A|)"];
100 [label="Exit when branch condition"];
}
subgraph cluster_25 {
color=blue
101 [label="Enter when branch condition "];
102 [label="Type operator: ($subj$ !is R|B|)"];
103 [label="Exit when branch condition"];
}
subgraph cluster_26 {
color=blue
104 [label="Enter when branch condition "];
105 [label="Type operator: ($subj$ is R|kotlin/Int|)"];
106 [label="Exit when branch condition"];
}
subgraph cluster_27 {
color=blue
107 [label="Enter when branch condition else"];
108 [label="Exit when branch condition"];
}
109 [label="Enter when branch result"];
subgraph cluster_28 {
color=blue
110 [label="Enter block"];
111 [label="Access variable R|<local>/x|"];
112 [label="Function call: R|<local>/x|.R|/A.foo|()"];
113 [label="Access variable R|<local>/x|"];
114 [label="Function call: R|<local>/x|.R|/B.bar|()"];
115 [label="Exit block"];
}
116 [label="Exit when branch result"];
117 [label="Enter when branch result"];
subgraph cluster_29 {
color=blue
118 [label="Enter block"];
119 [label="Access variable R|<local>/x|"];
120 [label="Function call: R|<local>/x|.R|/A.foo|()"];
121 [label="Access variable R|<local>/x|"];
122 [label="Function call: R|<local>/x|.R|/B.bar|()"];
123 [label="Access variable R|<local>/x|"];
124 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()"];
125 [label="Exit block"];
}
126 [label="Exit when branch result"];
127 [label="Enter when branch result"];
subgraph cluster_30 {
color=blue
128 [label="Enter block"];
129 [label="Access variable R|<local>/x|"];
130 [label="Function call: R|<local>/x|.R|/A.foo|()"];
131 [label="Exit block"];
}
132 [label="Exit when branch result"];
133 [label="Enter when branch result"];
subgraph cluster_31 {
color=blue
134 [label="Enter block"];
135 [label="Exit block"];
}
136 [label="Exit when branch result"];
137 [label="Exit when"];
}
138 [label="Exit function test_2" style="filled" fillcolor=red];
}
73 -> {74};
74 -> {75};
75 -> {76};
76 -> {77};
77 -> {78};
78 -> {89 79};
79 -> {80};
80 -> {81};
81 -> {83 82};
82 -> {95};
83 -> {84};
84 -> {85};
85 -> {86};
86 -> {87};
87 -> {88};
88 -> {95};
89 -> {90};
90 -> {91};
91 -> {92};
92 -> {93};
93 -> {94};
94 -> {95};
95 -> {96};
96 -> {97};
97 -> {98};
98 -> {99};
99 -> {100};
100 -> {133 101};
101 -> {102};
102 -> {103};
103 -> {127 104};
104 -> {105};
105 -> {106};
106 -> {117 107};
107 -> {108};
108 -> {109};
109 -> {110};
110 -> {111};
111 -> {112};
112 -> {113};
113 -> {114};
114 -> {115};
115 -> {116};
116 -> {137};
117 -> {118};
118 -> {119};
119 -> {120};
120 -> {121};
121 -> {122};
122 -> {123};
123 -> {124};
124 -> {125};
125 -> {126};
126 -> {137};
127 -> {128};
128 -> {129};
129 -> {130};
130 -> {131};
131 -> {132};
132 -> {137};
133 -> {134};
134 -> {135};
135 -> {136};
136 -> {137};
137 -> {138};
subgraph cluster_32 {
color=red
139 [label="Enter function test_3" style="filled" fillcolor=red];
subgraph cluster_33 {
color=blue
140 [label="Enter when"];
141 [label="Access variable R|<local>/x|"];
142 [label="Variable declaration: lval y: R|kotlin/Any?|"];
subgraph cluster_34 {
color=blue
143 [label="Enter when branch condition "];
144 [label="Type operator: ($subj$ is R|A|)"];
145 [label="Exit when branch condition"];
}
subgraph cluster_35 {
color=blue
146 [label="Enter when branch condition "];
147 [label="Type operator: ($subj$ is R|B|)"];
148 [label="Exit when branch condition"];
}
149 [label="Synthetic else branch"];
150 [label="Enter when branch result"];
subgraph cluster_36 {
color=blue
151 [label="Enter block"];
152 [label="Access variable R|<local>/x|"];
153 [label="Function call: R|<local>/x|.R|/B.bar|()"];
154 [label="Access variable R|<local>/y|"];
155 [label="Function call: R|<local>/y|.R|/B.bar|()"];
156 [label="Exit block"];
}
157 [label="Exit when branch result"];
158 [label="Enter when branch result"];
subgraph cluster_37 {
color=blue
159 [label="Enter block"];
160 [label="Access variable R|<local>/x|"];
161 [label="Function call: R|<local>/x|.R|/A.foo|()"];
162 [label="Access variable R|<local>/y|"];
163 [label="Function call: R|<local>/y|.R|/A.foo|()"];
164 [label="Exit block"];
}
165 [label="Exit when branch result"];
166 [label="Exit when"];
}
subgraph cluster_38 {
color=blue
167 [label="Enter when"];
168 [label="Access variable R|<local>/x|"];
169 [label="Variable declaration: lval y: R|kotlin/Any?|"];
subgraph cluster_39 {
color=blue
170 [label="Enter when branch condition "];
171 [label="Type operator: ($subj$ !is R|A|)"];
172 [label="Exit when branch condition"];
}
subgraph cluster_40 {
color=blue
173 [label="Enter when branch condition "];
174 [label="Type operator: ($subj$ !is R|B|)"];
175 [label="Exit when branch condition"];
}
subgraph cluster_41 {
color=blue
176 [label="Enter when branch condition "];
177 [label="Type operator: ($subj$ is R|kotlin/Int|)"];
178 [label="Exit when branch condition"];
}
subgraph cluster_42 {
color=blue
179 [label="Enter when branch condition else"];
180 [label="Exit when branch condition"];
}
181 [label="Enter when branch result"];
subgraph cluster_43 {
color=blue
182 [label="Enter block"];
183 [label="Access variable R|<local>/x|"];
184 [label="Function call: R|<local>/x|.R|/A.foo|()"];
185 [label="Access variable R|<local>/x|"];
186 [label="Function call: R|<local>/x|.R|/B.bar|()"];
187 [label="Access variable R|<local>/y|"];
188 [label="Function call: R|<local>/y|.R|/A.foo|()"];
189 [label="Access variable R|<local>/y|"];
190 [label="Function call: R|<local>/y|.R|/B.bar|()"];
191 [label="Exit block"];
}
192 [label="Exit when branch result"];
193 [label="Enter when branch result"];
subgraph cluster_44 {
color=blue
194 [label="Enter block"];
195 [label="Access variable R|<local>/x|"];
196 [label="Function call: R|<local>/x|.R|/A.foo|()"];
197 [label="Access variable R|<local>/x|"];
198 [label="Function call: R|<local>/x|.R|/B.bar|()"];
199 [label="Access variable R|<local>/x|"];
200 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()"];
201 [label="Access variable R|<local>/y|"];
202 [label="Function call: R|<local>/y|.R|/A.foo|()"];
203 [label="Access variable R|<local>/y|"];
204 [label="Function call: R|<local>/y|.R|/B.bar|()"];
205 [label="Access variable R|<local>/y|"];
206 [label="Function call: R|<local>/y|.R|kotlin/Int.inc|()"];
207 [label="Exit block"];
}
208 [label="Exit when branch result"];
209 [label="Enter when branch result"];
subgraph cluster_45 {
color=blue
210 [label="Enter block"];
211 [label="Access variable R|<local>/x|"];
212 [label="Function call: R|<local>/x|.R|/A.foo|()"];
213 [label="Access variable R|<local>/y|"];
214 [label="Function call: R|<local>/y|.R|/A.foo|()"];
215 [label="Exit block"];
}
216 [label="Exit when branch result"];
217 [label="Enter when branch result"];
subgraph cluster_46 {
color=blue
218 [label="Enter block"];
219 [label="Exit block"];
}
220 [label="Exit when branch result"];
221 [label="Exit when"];
}
222 [label="Exit function test_3" style="filled" fillcolor=red];
}
139 -> {140};
140 -> {141};
141 -> {142};
142 -> {143};
143 -> {144};
144 -> {145};
145 -> {158 146};
146 -> {147};
147 -> {148};
148 -> {150 149};
149 -> {166};
150 -> {151};
151 -> {152};
152 -> {153};
153 -> {154};
154 -> {155};
155 -> {156};
156 -> {157};
157 -> {166};
158 -> {159};
159 -> {160};
160 -> {161};
161 -> {162};
162 -> {163};
163 -> {164};
164 -> {165};
165 -> {166};
166 -> {167};
167 -> {168};
168 -> {169};
169 -> {170};
170 -> {171};
171 -> {172};
172 -> {217 173};
173 -> {174};
174 -> {175};
175 -> {209 176};
176 -> {177};
177 -> {178};
178 -> {193 179};
179 -> {180};
180 -> {181};
181 -> {182};
182 -> {183};
183 -> {184};
184 -> {185};
185 -> {186};
186 -> {187};
187 -> {188};
188 -> {189};
189 -> {190};
190 -> {191};
191 -> {192};
192 -> {221};
193 -> {194};
194 -> {195};
195 -> {196};
196 -> {197};
197 -> {198};
198 -> {199};
199 -> {200};
200 -> {201};
201 -> {202};
202 -> {203};
203 -> {204};
204 -> {205};
205 -> {206};
206 -> {207};
207 -> {208};
208 -> {221};
209 -> {210};
210 -> {211};
211 -> {212};
212 -> {213};
213 -> {214};
214 -> {215};
215 -> {216};
216 -> {221};
217 -> {218};
218 -> {219};
219 -> {220};
220 -> {221};
221 -> {222};
subgraph cluster_47 {
color=red
223 [label="Enter function test_4" style="filled" fillcolor=red];
subgraph cluster_48 {
color=blue
224 [label="Enter when"];
225 [label="Access variable R|<local>/x|"];
226 [label="Type operator: (R|<local>/x| as R|kotlin/Int|)"];
subgraph cluster_49 {
color=blue
227 [label="Enter when branch condition "];
228 [label="Const: Int(1)"];
229 [label="Operator =="];
230 [label="Exit when branch condition"];
}
231 [label="Synthetic else branch"];
232 [label="Enter when branch result"];
subgraph cluster_50 {
color=blue
233 [label="Enter block"];
234 [label="Access variable R|<local>/x|"];
235 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()"];
236 [label="Exit block"];
}
237 [label="Exit when branch result"];
238 [label="Exit when"];
}
239 [label="Access variable R|<local>/x|"];
240 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()"];
241 [label="Exit function test_4" style="filled" fillcolor=red];
}
223 -> {224};
224 -> {225};
225 -> {226};
226 -> {227};
227 -> {228};
228 -> {229};
229 -> {230};
230 -> {232 231};
231 -> {238};
232 -> {233};
233 -> {234};
234 -> {235};
235 -> {236};
236 -> {237};
237 -> {238};
238 -> {239};
239 -> {240};
240 -> {241};
}
@@ -0,0 +1,92 @@
// !DUMP_CFG
interface A {
fun foo()
}
interface B {
fun bar()
}
fun test_1(x: Any?) {
when {
x is A -> x.foo()
x is B -> x.bar()
}
when {
x !is A -> {}
x !is B -> x.foo()
x is Int -> {
x.foo()
x.bar()
x.inc()
}
else -> {
x.foo()
x.bar()
}
}
}
fun test_2(x: Any?) {
when(x) {
is A -> x.foo()
is B -> x.bar()
}
when(x) {
!is A -> {}
!is B -> x.foo()
is Int -> {
x.foo()
x.bar()
x.inc()
}
else -> {
x.foo()
x.bar()
}
}
}
fun test_3(x: Any?) {
when(val y = x) {
is A -> {
x.foo()
y.foo()
}
is B -> {
x.bar()
y.bar()
}
}
when(val y = x) {
!is A -> {}
!is B -> {
x.foo()
y.foo()
}
is Int -> {
x.foo()
x.bar()
x.inc()
y.foo()
y.bar()
y.inc()
}
else -> {
x.foo()
x.bar()
y.foo()
y.bar()
}
}
}
fun test_4(x: Any) {
when (x as Int) {
1 -> x.inc()
}
x.inc()
}
@@ -0,0 +1,110 @@
FILE: when.kt
public abstract interface A : R|kotlin/Any| {
public abstract fun foo(): R|kotlin/Unit|
}
public abstract interface B : R|kotlin/Any| {
public abstract fun bar(): R|kotlin/Unit|
}
public final fun test_1(x: R|kotlin/Any?|): R|kotlin/Unit| {
when () {
(R|<local>/x| is R|A|) -> {
R|<local>/x|.R|/A.foo|()
}
(R|<local>/x| is R|B|) -> {
R|<local>/x|.R|/B.bar|()
}
}
when () {
(R|<local>/x| !is R|A|) -> {
}
(R|<local>/x| !is R|B|) -> {
R|<local>/x|.R|/A.foo|()
}
(R|<local>/x| is R|kotlin/Int|) -> {
R|<local>/x|.R|/A.foo|()
R|<local>/x|.R|/B.bar|()
R|<local>/x|.R|kotlin/Int.inc|()
}
else -> {
R|<local>/x|.R|/A.foo|()
R|<local>/x|.R|/B.bar|()
}
}
}
public final fun test_2(x: R|kotlin/Any?|): R|kotlin/Unit| {
when (R|<local>/x|) {
($subj$ is R|A|) -> {
R|<local>/x|.R|/A.foo|()
}
($subj$ is R|B|) -> {
R|<local>/x|.R|/B.bar|()
}
}
when (R|<local>/x|) {
($subj$ !is R|A|) -> {
}
($subj$ !is R|B|) -> {
R|<local>/x|.R|/A.foo|()
}
($subj$ is R|kotlin/Int|) -> {
R|<local>/x|.R|/A.foo|()
R|<local>/x|.R|/B.bar|()
R|<local>/x|.R|kotlin/Int.inc|()
}
else -> {
R|<local>/x|.R|/A.foo|()
R|<local>/x|.R|/B.bar|()
}
}
}
public final fun test_3(x: R|kotlin/Any?|): R|kotlin/Unit| {
when (lval y: R|kotlin/Any?| = R|<local>/x|) {
($subj$ is R|A|) -> {
R|<local>/x|.R|/A.foo|()
R|<local>/y|.R|/A.foo|()
}
($subj$ is R|B|) -> {
R|<local>/x|.R|/B.bar|()
R|<local>/y|.R|/B.bar|()
}
}
when (lval y: R|kotlin/Any?| = R|<local>/x|) {
($subj$ !is R|A|) -> {
}
($subj$ !is R|B|) -> {
R|<local>/x|.R|/A.foo|()
R|<local>/y|.R|/A.foo|()
}
($subj$ is R|kotlin/Int|) -> {
R|<local>/x|.R|/A.foo|()
R|<local>/x|.R|/B.bar|()
R|<local>/x|.R|kotlin/Int.inc|()
R|<local>/y|.R|/A.foo|()
R|<local>/y|.R|/B.bar|()
R|<local>/y|.R|kotlin/Int.inc|()
}
else -> {
R|<local>/x|.R|/A.foo|()
R|<local>/x|.R|/B.bar|()
R|<local>/y|.R|/A.foo|()
R|<local>/y|.R|/B.bar|()
}
}
}
public final fun test_4(x: R|kotlin/Any|): R|kotlin/Unit| {
when ((R|<local>/x| as R|kotlin/Int|)) {
==($subj$, Int(1)) -> {
R|<local>/x|.R|kotlin/Int.inc|()
}
}
R|<local>/x|.R|kotlin/Int.inc|()
}
@@ -0,0 +1,322 @@
digraph equalsAndIdentity_kt {
graph [nodesep=3]
node [shape=box penwidth=2]
edge [penwidth=2]
subgraph cluster_0 {
color=red
0 [label="Enter function foo" style="filled" fillcolor=red];
1 [label="Exit function foo" style="filled" fillcolor=red];
}
0 -> {1};
subgraph cluster_1 {
color=red
2 [label="Enter function test_1" style="filled" fillcolor=red];
subgraph cluster_2 {
color=blue
3 [label="Enter when"];
subgraph cluster_3 {
color=blue
4 [label="Enter when branch condition "];
5 [label="Access variable R|<local>/x|"];
6 [label="Access variable R|<local>/y|"];
7 [label="Operator =="];
8 [label="Exit when branch condition"];
}
9 [label="Synthetic else branch"];
10 [label="Enter when branch result"];
subgraph cluster_4 {
color=blue
11 [label="Enter block"];
12 [label="Access variable R|<local>/x|"];
13 [label="Function call: R|<local>/x|.R|/A.foo|()"];
14 [label="Access variable R|<local>/y|"];
15 [label="Function call: R|<local>/y|.R|/A.foo|()"];
16 [label="Exit block"];
}
17 [label="Exit when branch result"];
18 [label="Exit when"];
}
subgraph cluster_5 {
color=blue
19 [label="Enter when"];
subgraph cluster_6 {
color=blue
20 [label="Enter when branch condition "];
21 [label="Access variable R|<local>/x|"];
22 [label="Access variable R|<local>/y|"];
23 [label="Operator ==="];
24 [label="Exit when branch condition"];
}
25 [label="Synthetic else branch"];
26 [label="Enter when branch result"];
subgraph cluster_7 {
color=blue
27 [label="Enter block"];
28 [label="Access variable R|<local>/x|"];
29 [label="Function call: R|<local>/x|.R|/A.foo|()"];
30 [label="Access variable R|<local>/y|"];
31 [label="Function call: R|<local>/y|.R|/A.foo|()"];
32 [label="Exit block"];
}
33 [label="Exit when branch result"];
34 [label="Exit when"];
}
35 [label="Exit function test_1" style="filled" fillcolor=red];
}
2 -> {3};
3 -> {4};
4 -> {5};
5 -> {6};
6 -> {7};
7 -> {8};
8 -> {10 9};
9 -> {18};
10 -> {11};
11 -> {12};
12 -> {13};
13 -> {14};
14 -> {15};
15 -> {16};
16 -> {17};
17 -> {18};
18 -> {19};
19 -> {20};
20 -> {21};
21 -> {22};
22 -> {23};
23 -> {24};
24 -> {26 25};
25 -> {34};
26 -> {27};
27 -> {28};
28 -> {29};
29 -> {30};
30 -> {31};
31 -> {32};
32 -> {33};
33 -> {34};
34 -> {35};
subgraph cluster_8 {
color=red
36 [label="Enter function test_2" style="filled" fillcolor=red];
subgraph cluster_9 {
color=blue
37 [label="Enter when"];
subgraph cluster_10 {
color=blue
38 [label="Enter when branch condition "];
39 [label="Access variable R|<local>/x|"];
40 [label="Access variable R|<local>/y|"];
41 [label="Operator =="];
42 [label="Exit when branch condition"];
}
43 [label="Synthetic else branch"];
44 [label="Enter when branch result"];
subgraph cluster_11 {
color=blue
45 [label="Enter block"];
46 [label="Access variable R|<local>/x|"];
47 [label="Function call: R|<local>/x|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()"];
48 [label="Access variable R|<local>/y|"];
49 [label="Function call: R|<local>/y|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()"];
50 [label="Exit block"];
}
51 [label="Exit when branch result"];
52 [label="Exit when"];
}
subgraph cluster_12 {
color=blue
53 [label="Enter when"];
subgraph cluster_13 {
color=blue
54 [label="Enter when branch condition "];
55 [label="Access variable R|<local>/x|"];
56 [label="Access variable R|<local>/y|"];
57 [label="Operator ==="];
58 [label="Exit when branch condition"];
}
59 [label="Synthetic else branch"];
60 [label="Enter when branch result"];
subgraph cluster_14 {
color=blue
61 [label="Enter block"];
62 [label="Access variable R|<local>/x|"];
63 [label="Function call: R|<local>/x|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()"];
64 [label="Access variable R|<local>/y|"];
65 [label="Function call: R|<local>/y|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()"];
66 [label="Exit block"];
}
67 [label="Exit when branch result"];
68 [label="Exit when"];
}
69 [label="Exit function test_2" style="filled" fillcolor=red];
}
36 -> {37};
37 -> {38};
38 -> {39};
39 -> {40};
40 -> {41};
41 -> {42};
42 -> {44 43};
43 -> {52};
44 -> {45};
45 -> {46};
46 -> {47};
47 -> {48};
48 -> {49};
49 -> {50};
50 -> {51};
51 -> {52};
52 -> {53};
53 -> {54};
54 -> {55};
55 -> {56};
56 -> {57};
57 -> {58};
58 -> {60 59};
59 -> {68};
60 -> {61};
61 -> {62};
62 -> {63};
63 -> {64};
64 -> {65};
65 -> {66};
66 -> {67};
67 -> {68};
68 -> {69};
subgraph cluster_15 {
color=red
70 [label="Enter function test_3" style="filled" fillcolor=red];
subgraph cluster_16 {
color=blue
71 [label="Enter when"];
subgraph cluster_17 {
color=blue
72 [label="Enter when branch condition "];
73 [label="Access variable R|<local>/y|"];
74 [label="Const: Null(null)"];
75 [label="Operator =="];
76 [label="Exit when branch condition"];
}
77 [label="Synthetic else branch"];
78 [label="Enter when branch result"];
subgraph cluster_18 {
color=blue
79 [label="Enter block"];
80 [label="Jump: ^test_3 Unit"];
81 [label="Stub" style="filled" fillcolor=gray];
82 [label="Exit block" style="filled" fillcolor=gray];
}
83 [label="Exit when branch result" style="filled" fillcolor=gray];
84 [label="Exit when"];
}
subgraph cluster_19 {
color=blue
85 [label="Enter when"];
subgraph cluster_20 {
color=blue
86 [label="Enter when branch condition "];
87 [label="Access variable R|<local>/x|"];
88 [label="Access variable R|<local>/y|"];
89 [label="Operator =="];
90 [label="Exit when branch condition"];
}
91 [label="Synthetic else branch"];
92 [label="Enter when branch result"];
subgraph cluster_21 {
color=blue
93 [label="Enter block"];
94 [label="Access variable R|<local>/x|"];
95 [label="Function call: R|<local>/x|.R|/A.foo|()"];
96 [label="Access variable R|<local>/y|"];
97 [label="Function call: R|<local>/y|.R|/A.foo|()"];
98 [label="Exit block"];
}
99 [label="Exit when branch result"];
100 [label="Exit when"];
}
subgraph cluster_22 {
color=blue
101 [label="Enter when"];
subgraph cluster_23 {
color=blue
102 [label="Enter when branch condition "];
103 [label="Access variable R|<local>/x|"];
104 [label="Access variable R|<local>/y|"];
105 [label="Operator ==="];
106 [label="Exit when branch condition"];
}
107 [label="Synthetic else branch"];
108 [label="Enter when branch result"];
subgraph cluster_24 {
color=blue
109 [label="Enter block"];
110 [label="Access variable R|<local>/x|"];
111 [label="Function call: R|<local>/x|.R|/A.foo|()"];
112 [label="Access variable R|<local>/y|"];
113 [label="Function call: R|<local>/y|.R|/A.foo|()"];
114 [label="Exit block"];
}
115 [label="Exit when branch result"];
116 [label="Exit when"];
}
117 [label="Exit function test_3" style="filled" fillcolor=red];
}
70 -> {71};
71 -> {72};
72 -> {73};
73 -> {74};
74 -> {75};
75 -> {76};
76 -> {78 77};
77 -> {84};
78 -> {79};
79 -> {80};
80 -> {117};
80 -> {81} [style=dotted];
81 -> {82} [style=dotted];
82 -> {83} [style=dotted];
83 -> {84} [style=dotted];
84 -> {85};
85 -> {86};
86 -> {87};
87 -> {88};
88 -> {89};
89 -> {90};
90 -> {92 91};
91 -> {100};
92 -> {93};
93 -> {94};
94 -> {95};
95 -> {96};
96 -> {97};
97 -> {98};
98 -> {99};
99 -> {100};
100 -> {101};
101 -> {102};
102 -> {103};
103 -> {104};
104 -> {105};
105 -> {106};
106 -> {108 107};
107 -> {116};
108 -> {109};
109 -> {110};
110 -> {111};
111 -> {112};
112 -> {113};
113 -> {114};
114 -> {115};
115 -> {116};
116 -> {117};
}
@@ -0,0 +1,38 @@
// !DUMP_CFG
interface A {
fun foo()
}
fun test_1(x: A, y: A?) {
if (x == y) {
x.foo()
y.foo()
}
if (x === y) {
x.foo()
y.foo()
}
}
fun test_2(x: A?, y: A?) {
if (x == y) {
x.<!INAPPLICABLE_CANDIDATE!>foo<!>()
y.<!INAPPLICABLE_CANDIDATE!>foo<!>()
}
if (x === y) {
x.<!INAPPLICABLE_CANDIDATE!>foo<!>()
y.<!INAPPLICABLE_CANDIDATE!>foo<!>()
}
}
fun test_3(x: A?, y: A?) {
if (y == null) return
if (x == y) {
x.foo()
y.foo()
}
if (x === y) {
x.foo()
y.foo()
}
}
@@ -0,0 +1,59 @@
FILE: equalsAndIdentity.kt
public abstract interface A : R|kotlin/Any| {
public abstract fun foo(): R|kotlin/Unit|
}
public final fun test_1(x: R|A|, y: R|A?|): R|kotlin/Unit| {
when () {
==(R|<local>/x|, R|<local>/y|) -> {
R|<local>/x|.R|/A.foo|()
R|<local>/y|.R|/A.foo|()
}
}
when () {
===(R|<local>/x|, R|<local>/y|) -> {
R|<local>/x|.R|/A.foo|()
R|<local>/y|.R|/A.foo|()
}
}
}
public final fun test_2(x: R|A?|, y: R|A?|): R|kotlin/Unit| {
when () {
==(R|<local>/x|, R|<local>/y|) -> {
R|<local>/x|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()
R|<local>/y|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()
}
}
when () {
===(R|<local>/x|, R|<local>/y|) -> {
R|<local>/x|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()
R|<local>/y|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()
}
}
}
public final fun test_3(x: R|A?|, y: R|A?|): R|kotlin/Unit| {
when () {
==(R|<local>/y|, Null(null)) -> {
^test_3 Unit
}
}
when () {
==(R|<local>/x|, R|<local>/y|) -> {
R|<local>/x|.R|/A.foo|()
R|<local>/y|.R|/A.foo|()
}
}
when () {
===(R|<local>/x|, R|<local>/y|) -> {
R|<local>/x|.R|/A.foo|()
R|<local>/y|.R|/A.foo|()
}
}
}
@@ -0,0 +1,14 @@
// ISSUE: KT-37327
interface Q
sealed class A : Q
class B(val x: Int) : A()
fun Q.foo() {
if (this !is A) return
when (this) {
is B -> x // unresolved
}
}
@@ -0,0 +1,32 @@
FILE: kt37327.kt
public abstract interface Q : R|kotlin/Any| {
}
public sealed class A : R|Q| {
private constructor(): R|A| {
super<R|kotlin/Any|>()
}
}
public final class B : R|A| {
public constructor(x: R|kotlin/Int|): R|B| {
super<R|A|>()
}
public final val x: R|kotlin/Int| = R|<local>/x|
public get(): R|kotlin/Int|
}
public final fun R|Q|.foo(): R|kotlin/Unit| {
when () {
(this@R|/foo| !is R|A|) -> {
^foo Unit
}
}
when (this@R|/foo|) {
($subj$ is R|B|) -> {
this@R|/foo|.R|/B.x|
}
}
}
@@ -0,0 +1,183 @@
digraph inPlaceLambdas_kt {
graph [nodesep=3]
node [shape=box penwidth=2]
edge [penwidth=2]
subgraph cluster_0 {
color=red
0 [label="Enter function foo" style="filled" fillcolor=red];
1 [label="Exit function foo" style="filled" fillcolor=red];
}
0 -> {1};
subgraph cluster_1 {
color=red
2 [label="Enter function bar" style="filled" fillcolor=red];
3 [label="Exit function bar" style="filled" fillcolor=red];
}
2 -> {3};
subgraph cluster_2 {
color=red
4 [label="Enter function test_1" style="filled" fillcolor=red];
subgraph cluster_3 {
color=blue
5 [label="Enter when"];
subgraph cluster_4 {
color=blue
6 [label="Enter when branch condition "];
7 [label="Access variable R|<local>/x|"];
8 [label="Type operator: (R|<local>/x| is R|A|)"];
9 [label="Exit when branch condition"];
}
10 [label="Synthetic else branch"];
11 [label="Enter when branch result"];
subgraph cluster_5 {
color=blue
12 [label="Enter block"];
13 [label="Postponed enter to lambda"];
subgraph cluster_6 {
color=blue
14 [label="Enter function anonymousFunction"];
15 [label="Access variable R|<local>/x|"];
16 [label="Function call: R|<local>/x|.R|/A.foo|()"];
17 [label="Exit function anonymousFunction"];
}
18 [label="Call arguments union" style="filled" fillcolor=yellow];
19 [label="Postponed exit from lambda"];
20 [label="Function call: R|kotlin/run|<R|kotlin/Unit|>(...)"];
21 [label="Exit block"];
}
22 [label="Exit when branch result"];
23 [label="Exit when"];
}
24 [label="Exit function test_1" style="filled" fillcolor=red];
}
4 -> {5};
5 -> {6};
6 -> {7};
7 -> {8};
8 -> {9};
9 -> {11 10};
10 -> {23};
11 -> {12};
12 -> {13};
13 -> {14};
13 -> {19} [color=red];
14 -> {15};
15 -> {16};
16 -> {17};
17 -> {19} [color=green];
17 -> {18} [color=red];
18 -> {20} [color=red];
19 -> {20} [color=green];
20 -> {21};
21 -> {22};
22 -> {23};
23 -> {24};
subgraph cluster_7 {
color=red
25 [label="Enter function test_2" style="filled" fillcolor=red];
26 [label="Postponed enter to lambda"];
subgraph cluster_8 {
color=blue
27 [label="Enter function anonymousFunction"];
28 [label="Access variable R|<local>/x|"];
29 [label="Type operator: (R|<local>/x| as R|B|)"];
30 [label="Exit function anonymousFunction"];
}
31 [label="Call arguments union" style="filled" fillcolor=yellow];
32 [label="Postponed exit from lambda"];
33 [label="Function call: R|kotlin/run|<R|B|>(...)"];
34 [label="Access variable R|<local>/x|"];
35 [label="Function call: R|<local>/x|.R|/B.bar|()"];
36 [label="Exit function test_2" style="filled" fillcolor=red];
}
25 -> {26};
26 -> {27};
26 -> {32} [color=red];
27 -> {28};
28 -> {29};
29 -> {30};
30 -> {32} [color=green];
30 -> {31} [color=red];
31 -> {33} [color=red];
32 -> {33} [color=green];
33 -> {34};
34 -> {35};
35 -> {36};
subgraph cluster_9 {
color=red
37 [label="Enter function test_3" style="filled" fillcolor=red];
subgraph cluster_10 {
color=blue
38 [label="Enter when"];
subgraph cluster_11 {
color=blue
39 [label="Enter when branch condition "];
40 [label="Access variable R|<local>/x|"];
41 [label="Type operator: (R|<local>/x| is R|A|)"];
42 [label="Exit when branch condition"];
}
43 [label="Synthetic else branch"];
44 [label="Enter when branch result"];
subgraph cluster_12 {
color=blue
45 [label="Enter block"];
46 [label="Postponed enter to lambda"];
subgraph cluster_13 {
color=blue
47 [label="Enter function anonymousFunction"];
48 [label="Access variable R|<local>/x|"];
49 [label="Function call: R|<local>/x|.R|/A.foo|()"];
50 [label="Access variable R|<local>/x|"];
51 [label="Type operator: (R|<local>/x| as R|B|)"];
52 [label="Exit function anonymousFunction"];
}
53 [label="Call arguments union" style="filled" fillcolor=yellow];
54 [label="Postponed exit from lambda"];
55 [label="Function call: R|kotlin/run|<R|B|>(...)"];
56 [label="Access variable R|<local>/x|"];
57 [label="Function call: R|<local>/x|.R|/B.bar|()"];
58 [label="Exit block"];
}
59 [label="Exit when branch result"];
60 [label="Exit when"];
}
61 [label="Exit function test_3" style="filled" fillcolor=red];
}
37 -> {38};
38 -> {39};
39 -> {40};
40 -> {41};
41 -> {42};
42 -> {44 43};
43 -> {60};
44 -> {45};
45 -> {46};
46 -> {47};
46 -> {54} [color=red];
47 -> {48};
48 -> {49};
49 -> {50};
50 -> {51};
51 -> {52};
52 -> {54} [color=green];
52 -> {53} [color=red];
53 -> {55} [color=red];
54 -> {55} [color=green];
55 -> {56};
56 -> {57};
57 -> {58};
58 -> {59};
59 -> {60};
60 -> {61};
}
@@ -0,0 +1,33 @@
// !DUMP_CFG
interface A {
fun foo()
}
interface B {
fun bar()
}
fun test_1(x: Any?) {
if (x is A) {
run {
x.foo()
}
}
}
fun test_2(x: Any?) {
run {
x as B
}
x.bar()
}
fun test_3(x: Any?) {
if (x is A) {
run {
x.foo()
x as B
}
x.bar()
}
}
@@ -0,0 +1,40 @@
FILE: inPlaceLambdas.kt
public abstract interface A : R|kotlin/Any| {
public abstract fun foo(): R|kotlin/Unit|
}
public abstract interface B : R|kotlin/Any| {
public abstract fun bar(): R|kotlin/Unit|
}
public final fun test_1(x: R|kotlin/Any?|): R|kotlin/Unit| {
when () {
(R|<local>/x| is R|A|) -> {
R|kotlin/run|<R|kotlin/Unit|>(<L> = run@fun <anonymous>(): R|kotlin/Unit| <kind=EXACTLY_ONCE> {
R|<local>/x|.R|/A.foo|()
}
)
}
}
}
public final fun test_2(x: R|kotlin/Any?|): R|kotlin/Unit| {
R|kotlin/run|<R|B|>(<L> = run@fun <anonymous>(): R|B| <kind=EXACTLY_ONCE> {
^ (R|<local>/x| as R|B|)
}
)
R|<local>/x|.R|/B.bar|()
}
public final fun test_3(x: R|kotlin/Any?|): R|kotlin/Unit| {
when () {
(R|<local>/x| is R|A|) -> {
R|kotlin/run|<R|B|>(<L> = run@fun <anonymous>(): R|B| <kind=EXACTLY_ONCE> {
R|<local>/x|.R|/A.foo|()
^ (R|<local>/x| as R|B|)
}
)
R|<local>/x|.R|/B.bar|()
}
}
}
@@ -0,0 +1,49 @@
digraph smartcastOnLambda_kt {
graph [nodesep=3]
node [shape=box penwidth=2]
edge [penwidth=2]
subgraph cluster_0 {
color=red
0 [label="Enter function test" style="filled" fillcolor=red];
subgraph cluster_1 {
color=blue
1 [label="Enter when"];
subgraph cluster_2 {
color=blue
2 [label="Enter when branch condition "];
3 [label="Access variable R|<local>/func|"];
4 [label="Const: Null(null)"];
5 [label="Operator !="];
6 [label="Exit when branch condition"];
}
7 [label="Synthetic else branch"];
8 [label="Enter when branch result"];
subgraph cluster_3 {
color=blue
9 [label="Enter block"];
10 [label="Function call: R|<local>/func|.R|FakeOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()"];
11 [label="Exit block"];
}
12 [label="Exit when branch result"];
13 [label="Exit when"];
}
14 [label="Exit function test" style="filled" fillcolor=red];
}
0 -> {1};
1 -> {2};
2 -> {3};
3 -> {4};
4 -> {5};
5 -> {6};
6 -> {8 7};
7 -> {13};
8 -> {9};
9 -> {10};
10 -> {11};
11 -> {12};
12 -> {13};
13 -> {14};
}
@@ -0,0 +1,6 @@
// !DUMP_CFG
fun test(func: (() -> Unit)?) {
if (func != null) {
func()
}
}
@@ -0,0 +1,9 @@
FILE: smartcastOnLambda.kt
public final fun test(func: R|() -> kotlin/Unit|): R|kotlin/Unit| {
when () {
!=(R|<local>/func|, Null(null)) -> {
R|<local>/func|.R|FakeOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
}
}
}
@@ -0,0 +1,77 @@
digraph dataFlowInfoFromWhileCondition_kt {
graph [nodesep=3]
node [shape=box penwidth=2]
edge [penwidth=2]
subgraph cluster_0 {
color=red
0 [label="Enter function foo" style="filled" fillcolor=red];
1 [label="Exit function foo" style="filled" fillcolor=red];
}
0 -> {1};
subgraph cluster_1 {
color=red
2 [label="Enter function test" style="filled" fillcolor=red];
3 [label="Const: Null(null)"];
4 [label="Variable declaration: lvar a: R|A?|"];
subgraph cluster_2 {
color=blue
5 [label="Enter while loop"];
subgraph cluster_3 {
color=blue
6 [label="Enter loop condition"];
subgraph cluster_4 {
color=blue
7 [label="Enter ||"];
8 [label="Access variable R|<local>/a|"];
9 [label="Type operator: (R|<local>/a| is R|B|)"];
10 [label="Exit left part of ||"];
11 [label="Enter right part of ||"];
12 [label="Access variable R|<local>/a|"];
13 [label="Type operator: (R|<local>/a| is R|C|)"];
14 [label="Exit ||"];
}
15 [label="Exit loop condition"];
}
subgraph cluster_5 {
color=blue
16 [label="Enter loop block"];
subgraph cluster_6 {
color=blue
17 [label="Enter block"];
18 [label="Access variable R|<local>/a|"];
19 [label="Function call: R|<local>/a|.R|/A.foo|()"];
20 [label="Exit block"];
}
21 [label="Exit loop block"];
}
22 [label="Exit whileloop"];
}
23 [label="Exit function test" style="filled" fillcolor=red];
}
2 -> {3};
3 -> {4};
4 -> {5};
5 -> {6};
6 -> {7};
7 -> {8};
8 -> {9};
9 -> {10};
10 -> {14 11};
11 -> {12};
12 -> {13};
13 -> {14};
14 -> {15};
15 -> {22 16};
16 -> {17};
17 -> {18};
18 -> {19};
19 -> {20};
20 -> {21};
21 -> {6};
22 -> {23};
}
@@ -0,0 +1,13 @@
// !DUMP_CFG
interface A {
fun foo(): Boolean
}
interface B : A
interface C : A
fun test() {
var a: A? = null
while (a is B || a is C) {
a.foo()
}
}
@@ -0,0 +1,16 @@
FILE: dataFlowInfoFromWhileCondition.kt
public abstract interface A : R|kotlin/Any| {
public abstract fun foo(): R|kotlin/Boolean|
}
public abstract interface B : R|A| {
}
public abstract interface C : R|A| {
}
public final fun test(): R|kotlin/Unit| {
lvar a: R|A?| = Null(null)
while((R|<local>/a| is R|B|) || (R|<local>/a| is R|C|)) {
R|<local>/a|.R|/A.foo|()
}
}
@@ -0,0 +1,586 @@
digraph endlessLoops_kt {
graph [nodesep=3]
node [shape=box penwidth=2]
edge [penwidth=2]
subgraph cluster_0 {
color=red
0 [label="Enter function foo" style="filled" fillcolor=red];
1 [label="Exit function foo" style="filled" fillcolor=red];
}
0 -> {1};
subgraph cluster_1 {
color=red
2 [label="Enter function test_1" style="filled" fillcolor=red];
subgraph cluster_2 {
color=blue
3 [label="Enter while loop"];
subgraph cluster_3 {
color=blue
4 [label="Enter loop condition"];
5 [label="Const: Boolean(true)"];
6 [label="Exit loop condition"];
}
subgraph cluster_4 {
color=blue
7 [label="Enter loop block"];
subgraph cluster_5 {
color=blue
8 [label="Enter block"];
9 [label="Access variable R|<local>/x|"];
10 [label="Type operator: (R|<local>/x| as R|A|)"];
subgraph cluster_6 {
color=blue
11 [label="Enter when"];
subgraph cluster_7 {
color=blue
12 [label="Enter when branch condition "];
13 [label="Access variable R|<local>/b|"];
14 [label="Exit when branch condition"];
}
15 [label="Synthetic else branch"];
16 [label="Enter when branch result"];
subgraph cluster_8 {
color=blue
17 [label="Enter block"];
18 [label="Jump: break@@@[Boolean(true)] "];
19 [label="Stub" style="filled" fillcolor=gray];
20 [label="Exit block" style="filled" fillcolor=gray];
}
21 [label="Exit when branch result" style="filled" fillcolor=gray];
22 [label="Exit when"];
}
23 [label="Exit block"];
}
24 [label="Exit loop block"];
}
25 [label="Exit whileloop"];
}
26 [label="Access variable R|<local>/x|"];
27 [label="Function call: R|<local>/x|.R|/A.foo|()"];
28 [label="Exit function test_1" style="filled" fillcolor=red];
}
2 -> {3};
3 -> {4};
4 -> {5};
5 -> {6};
6 -> {7};
6 -> {25} [style=dotted];
7 -> {8};
8 -> {9};
9 -> {10};
10 -> {11};
11 -> {12};
12 -> {13};
13 -> {14};
14 -> {16 15};
15 -> {22};
16 -> {17};
17 -> {18};
18 -> {25};
18 -> {19} [style=dotted];
19 -> {20} [style=dotted];
20 -> {21} [style=dotted];
21 -> {22} [style=dotted];
22 -> {23};
23 -> {24};
24 -> {4};
25 -> {26};
26 -> {27};
27 -> {28};
subgraph cluster_9 {
color=red
29 [label="Enter function test_2" style="filled" fillcolor=red];
subgraph cluster_10 {
color=blue
30 [label="Enter while loop"];
subgraph cluster_11 {
color=blue
31 [label="Enter loop condition"];
32 [label="Const: Boolean(true)"];
33 [label="Exit loop condition"];
}
subgraph cluster_12 {
color=blue
34 [label="Enter loop block"];
subgraph cluster_13 {
color=blue
35 [label="Enter block"];
subgraph cluster_14 {
color=blue
36 [label="Enter when"];
subgraph cluster_15 {
color=blue
37 [label="Enter when branch condition "];
38 [label="Access variable R|<local>/b|"];
39 [label="Exit when branch condition"];
}
40 [label="Synthetic else branch"];
41 [label="Enter when branch result"];
subgraph cluster_16 {
color=blue
42 [label="Enter block"];
43 [label="Access variable R|<local>/x|"];
44 [label="Type operator: (R|<local>/x| as R|A|)"];
45 [label="Jump: break@@@[Boolean(true)] "];
46 [label="Stub" style="filled" fillcolor=gray];
47 [label="Exit block" style="filled" fillcolor=gray];
}
48 [label="Exit when branch result" style="filled" fillcolor=gray];
49 [label="Exit when"];
}
50 [label="Exit block"];
}
51 [label="Exit loop block"];
}
52 [label="Exit whileloop"];
}
53 [label="Access variable R|<local>/x|"];
54 [label="Function call: R|<local>/x|.R|/A.foo|()"];
55 [label="Exit function test_2" style="filled" fillcolor=red];
}
29 -> {30};
30 -> {31};
31 -> {32};
32 -> {33};
33 -> {34};
33 -> {52} [style=dotted];
34 -> {35};
35 -> {36};
36 -> {37};
37 -> {38};
38 -> {39};
39 -> {41 40};
40 -> {49};
41 -> {42};
42 -> {43};
43 -> {44};
44 -> {45};
45 -> {52};
45 -> {46} [style=dotted];
46 -> {47} [style=dotted];
47 -> {48} [style=dotted];
48 -> {49} [style=dotted];
49 -> {50};
50 -> {51};
51 -> {31};
52 -> {53};
53 -> {54};
54 -> {55};
subgraph cluster_17 {
color=red
56 [label="Enter function test_3" style="filled" fillcolor=red];
subgraph cluster_18 {
color=blue
57 [label="Enter while loop"];
subgraph cluster_19 {
color=blue
58 [label="Enter loop condition"];
59 [label="Const: Boolean(true)"];
60 [label="Exit loop condition"];
}
subgraph cluster_20 {
color=blue
61 [label="Enter loop block"];
subgraph cluster_21 {
color=blue
62 [label="Enter block"];
63 [label="Access variable R|<local>/x|"];
64 [label="Type operator: (R|<local>/x| as R|A|)"];
subgraph cluster_22 {
color=blue
65 [label="Enter when"];
subgraph cluster_23 {
color=blue
66 [label="Enter when branch condition "];
67 [label="Access variable R|<local>/b|"];
68 [label="Exit when branch condition"];
}
69 [label="Synthetic else branch"];
70 [label="Enter when branch result"];
subgraph cluster_24 {
color=blue
71 [label="Enter block"];
72 [label="Jump: break@@@[Boolean(true)] "];
73 [label="Stub" style="filled" fillcolor=gray];
74 [label="Exit block" style="filled" fillcolor=gray];
}
75 [label="Exit when branch result" style="filled" fillcolor=gray];
76 [label="Exit when"];
}
subgraph cluster_25 {
color=blue
77 [label="Enter when"];
subgraph cluster_26 {
color=blue
78 [label="Enter when branch condition "];
79 [label="Access variable R|<local>/b|"];
80 [label="Exit when branch condition"];
}
81 [label="Synthetic else branch"];
82 [label="Enter when branch result"];
subgraph cluster_27 {
color=blue
83 [label="Enter block"];
84 [label="Jump: break@@@[Boolean(true)] "];
85 [label="Stub" style="filled" fillcolor=gray];
86 [label="Exit block" style="filled" fillcolor=gray];
}
87 [label="Exit when branch result" style="filled" fillcolor=gray];
88 [label="Exit when"];
}
89 [label="Exit block"];
}
90 [label="Exit loop block"];
}
91 [label="Exit whileloop"];
}
92 [label="Access variable R|<local>/x|"];
93 [label="Function call: R|<local>/x|.R|/A.foo|()"];
94 [label="Exit function test_3" style="filled" fillcolor=red];
}
56 -> {57};
57 -> {58};
58 -> {59};
59 -> {60};
60 -> {61};
60 -> {91} [style=dotted];
61 -> {62};
62 -> {63};
63 -> {64};
64 -> {65};
65 -> {66};
66 -> {67};
67 -> {68};
68 -> {70 69};
69 -> {76};
70 -> {71};
71 -> {72};
72 -> {91};
72 -> {73} [style=dotted];
73 -> {74} [style=dotted];
74 -> {75} [style=dotted];
75 -> {76} [style=dotted];
76 -> {77};
77 -> {78};
78 -> {79};
79 -> {80};
80 -> {82 81};
81 -> {88};
82 -> {83};
83 -> {84};
84 -> {91};
84 -> {85} [style=dotted];
85 -> {86} [style=dotted];
86 -> {87} [style=dotted];
87 -> {88} [style=dotted];
88 -> {89};
89 -> {90};
90 -> {58};
91 -> {92};
92 -> {93};
93 -> {94};
subgraph cluster_28 {
color=red
95 [label="Enter function test_4" style="filled" fillcolor=red];
subgraph cluster_29 {
color=blue
96 [label="Enter while loop"];
subgraph cluster_30 {
color=blue
97 [label="Enter loop condition"];
98 [label="Const: Boolean(true)"];
99 [label="Exit loop condition"];
}
subgraph cluster_31 {
color=blue
100 [label="Enter loop block"];
subgraph cluster_32 {
color=blue
101 [label="Enter block"];
subgraph cluster_33 {
color=blue
102 [label="Enter when"];
subgraph cluster_34 {
color=blue
103 [label="Enter when branch condition "];
104 [label="Access variable R|<local>/b|"];
105 [label="Exit when branch condition"];
}
106 [label="Synthetic else branch"];
107 [label="Enter when branch result"];
subgraph cluster_35 {
color=blue
108 [label="Enter block"];
109 [label="Access variable R|<local>/x|"];
110 [label="Type operator: (R|<local>/x| as R|A|)"];
111 [label="Jump: break@@@[Boolean(true)] "];
112 [label="Stub" style="filled" fillcolor=gray];
113 [label="Exit block" style="filled" fillcolor=gray];
}
114 [label="Exit when branch result" style="filled" fillcolor=gray];
115 [label="Exit when"];
}
116 [label="Jump: break@@@[Boolean(true)] "];
117 [label="Stub" style="filled" fillcolor=gray];
118 [label="Exit block" style="filled" fillcolor=gray];
}
119 [label="Exit loop block" style="filled" fillcolor=gray];
}
120 [label="Exit whileloop"];
}
121 [label="Access variable R|<local>/x|"];
122 [label="Function call: R|<local>/x|.<Unresolved name: foo>#()"];
123 [label="Exit function test_4" style="filled" fillcolor=red];
}
95 -> {96};
96 -> {97};
97 -> {98};
98 -> {99};
99 -> {100};
99 -> {120} [style=dotted];
100 -> {101};
101 -> {102};
102 -> {103};
103 -> {104};
104 -> {105};
105 -> {107 106};
106 -> {115};
107 -> {108};
108 -> {109};
109 -> {110};
110 -> {111};
111 -> {120};
111 -> {112} [style=dotted];
112 -> {113} [style=dotted];
113 -> {114} [style=dotted];
114 -> {115} [style=dotted];
115 -> {116};
116 -> {120};
116 -> {117} [style=dotted];
117 -> {118} [style=dotted];
118 -> {119} [style=dotted];
119 -> {97} [style=dotted];
120 -> {121};
121 -> {122};
122 -> {123};
subgraph cluster_36 {
color=red
124 [label="Enter function test_5" style="filled" fillcolor=red];
subgraph cluster_37 {
color=blue
125 [label="Enter do-while loop"];
subgraph cluster_38 {
color=blue
126 [label="Enter loop block"];
subgraph cluster_39 {
color=blue
127 [label="Enter block"];
subgraph cluster_40 {
color=blue
128 [label="Enter when"];
subgraph cluster_41 {
color=blue
129 [label="Enter when branch condition "];
130 [label="Access variable R|<local>/b|"];
131 [label="Exit when branch condition"];
}
132 [label="Synthetic else branch"];
133 [label="Enter when branch result"];
subgraph cluster_42 {
color=blue
134 [label="Enter block"];
135 [label="Access variable R|<local>/x|"];
136 [label="Type operator: (R|<local>/x| as R|A|)"];
137 [label="Jump: break@@@[Boolean(true)] "];
138 [label="Stub" style="filled" fillcolor=gray];
139 [label="Exit block" style="filled" fillcolor=gray];
}
140 [label="Exit when branch result" style="filled" fillcolor=gray];
141 [label="Exit when"];
}
142 [label="Exit block"];
}
143 [label="Exit loop block"];
}
subgraph cluster_43 {
color=blue
144 [label="Enter loop condition"];
145 [label="Const: Boolean(true)"];
146 [label="Exit loop condition"];
}
147 [label="Exit do-whileloop"];
}
148 [label="Access variable R|<local>/x|"];
149 [label="Function call: R|<local>/x|.R|/A.foo|()"];
150 [label="Exit function test_5" style="filled" fillcolor=red];
}
124 -> {125};
125 -> {126};
126 -> {127};
127 -> {128};
128 -> {129};
129 -> {130};
130 -> {131};
131 -> {133 132};
132 -> {141};
133 -> {134};
134 -> {135};
135 -> {136};
136 -> {137};
137 -> {147};
137 -> {138} [style=dotted];
138 -> {139} [style=dotted];
139 -> {140} [style=dotted];
140 -> {141} [style=dotted];
141 -> {142};
142 -> {143};
143 -> {144};
144 -> {145};
145 -> {146};
146 -> {126};
146 -> {147} [style=dotted];
147 -> {148};
148 -> {149};
149 -> {150};
subgraph cluster_44 {
color=red
151 [label="Enter function test_6" style="filled" fillcolor=red];
subgraph cluster_45 {
color=blue
152 [label="Enter do-while loop"];
subgraph cluster_46 {
color=blue
153 [label="Enter loop block"];
subgraph cluster_47 {
color=blue
154 [label="Enter block"];
155 [label="Access variable R|<local>/x|"];
156 [label="Type operator: (R|<local>/x| as R|A|)"];
subgraph cluster_48 {
color=blue
157 [label="Enter when"];
subgraph cluster_49 {
color=blue
158 [label="Enter when branch condition "];
159 [label="Access variable R|<local>/b|"];
160 [label="Exit when branch condition"];
}
161 [label="Synthetic else branch"];
162 [label="Enter when branch result"];
subgraph cluster_50 {
color=blue
163 [label="Enter block"];
164 [label="Jump: break@@@[Boolean(true)] "];
165 [label="Stub" style="filled" fillcolor=gray];
166 [label="Exit block" style="filled" fillcolor=gray];
}
167 [label="Exit when branch result" style="filled" fillcolor=gray];
168 [label="Exit when"];
}
169 [label="Exit block"];
}
170 [label="Exit loop block"];
}
subgraph cluster_51 {
color=blue
171 [label="Enter loop condition"];
172 [label="Const: Boolean(true)"];
173 [label="Exit loop condition"];
}
174 [label="Exit do-whileloop"];
}
175 [label="Access variable R|<local>/x|"];
176 [label="Function call: R|<local>/x|.R|/A.foo|()"];
177 [label="Exit function test_6" style="filled" fillcolor=red];
}
151 -> {152};
152 -> {153};
153 -> {154};
154 -> {155};
155 -> {156};
156 -> {157};
157 -> {158};
158 -> {159};
159 -> {160};
160 -> {162 161};
161 -> {168};
162 -> {163};
163 -> {164};
164 -> {174};
164 -> {165} [style=dotted];
165 -> {166} [style=dotted];
166 -> {167} [style=dotted];
167 -> {168} [style=dotted];
168 -> {169};
169 -> {170};
170 -> {171};
171 -> {172};
172 -> {173};
173 -> {153};
173 -> {174} [style=dotted];
174 -> {175};
175 -> {176};
176 -> {177};
subgraph cluster_52 {
color=red
178 [label="Enter function test_7" style="filled" fillcolor=red];
subgraph cluster_53 {
color=blue
179 [label="Enter do-while loop"];
subgraph cluster_54 {
color=blue
180 [label="Enter loop block"];
subgraph cluster_55 {
color=blue
181 [label="Enter block"];
182 [label="Access variable R|<local>/x|"];
183 [label="Type operator: (R|<local>/x| as R|A|)"];
184 [label="Exit block"];
}
185 [label="Exit loop block"];
}
subgraph cluster_56 {
color=blue
186 [label="Enter loop condition"];
187 [label="Const: Boolean(true)"];
188 [label="Exit loop condition"];
}
189 [label="Exit do-whileloop" style="filled" fillcolor=gray];
}
190 [label="Access variable R|<local>/x|" style="filled" fillcolor=gray];
191 [label="Function call: R|<local>/x|.R|/A.foo|()" style="filled" fillcolor=gray];
192 [label="Exit function test_7" style="filled" fillcolor=red style="filled" fillcolor=gray];
}
178 -> {179};
179 -> {180};
180 -> {181};
181 -> {182};
182 -> {183};
183 -> {184};
184 -> {185};
185 -> {186};
186 -> {187};
187 -> {188};
188 -> {180};
188 -> {189} [style=dotted];
189 -> {190} [style=dotted];
190 -> {191} [style=dotted];
191 -> {192} [style=dotted];
}
@@ -0,0 +1,75 @@
// !DUMP_CFG
interface A {
fun foo()
}
fun test_1(x: Any, b: Boolean) {
while (true) {
x as A
if (b) {
break
}
}
x.foo()
}
fun test_2(x: Any, b: Boolean) {
while (true) {
if (b) {
x as A
break
}
}
x.foo()
}
fun test_3(x: Any, b: Boolean) {
while (true) {
x as A
if (b) {
break
}
if (b) {
break
}
}
x.foo()
}
fun test_4(x: Any, b: Boolean) {
while (true) {
if (b) {
x as A
break
}
break
}
x.<!UNRESOLVED_REFERENCE!>foo<!>() // No smartcast
}
fun test_5(x: Any, b: Boolean) {
do {
if (b) {
x as A
break
}
} while (true)
x.foo()
}
fun test_6(x: Any, b: Boolean) {
do {
x as A
if (b) {
break
}
} while (true)
x.foo()
}
fun test_7(x: Any) {
do {
x as A
} while (true)
x.foo()
}
@@ -0,0 +1,97 @@
FILE: endlessLoops.kt
public abstract interface A : R|kotlin/Any| {
public abstract fun foo(): R|kotlin/Unit|
}
public final fun test_1(x: R|kotlin/Any|, b: R|kotlin/Boolean|): R|kotlin/Unit| {
while(Boolean(true)) {
(R|<local>/x| as R|A|)
when () {
R|<local>/b| -> {
break@@@[Boolean(true)]
}
}
}
R|<local>/x|.R|/A.foo|()
}
public final fun test_2(x: R|kotlin/Any|, b: R|kotlin/Boolean|): R|kotlin/Unit| {
while(Boolean(true)) {
when () {
R|<local>/b| -> {
(R|<local>/x| as R|A|)
break@@@[Boolean(true)]
}
}
}
R|<local>/x|.R|/A.foo|()
}
public final fun test_3(x: R|kotlin/Any|, b: R|kotlin/Boolean|): R|kotlin/Unit| {
while(Boolean(true)) {
(R|<local>/x| as R|A|)
when () {
R|<local>/b| -> {
break@@@[Boolean(true)]
}
}
when () {
R|<local>/b| -> {
break@@@[Boolean(true)]
}
}
}
R|<local>/x|.R|/A.foo|()
}
public final fun test_4(x: R|kotlin/Any|, b: R|kotlin/Boolean|): R|kotlin/Unit| {
while(Boolean(true)) {
when () {
R|<local>/b| -> {
(R|<local>/x| as R|A|)
break@@@[Boolean(true)]
}
}
break@@@[Boolean(true)]
}
R|<local>/x|.<Unresolved name: foo>#()
}
public final fun test_5(x: R|kotlin/Any|, b: R|kotlin/Boolean|): R|kotlin/Unit| {
do {
when () {
R|<local>/b| -> {
(R|<local>/x| as R|A|)
break@@@[Boolean(true)]
}
}
}
while(Boolean(true))
R|<local>/x|.R|/A.foo|()
}
public final fun test_6(x: R|kotlin/Any|, b: R|kotlin/Boolean|): R|kotlin/Unit| {
do {
(R|<local>/x| as R|A|)
when () {
R|<local>/b| -> {
break@@@[Boolean(true)]
}
}
}
while(Boolean(true))
R|<local>/x|.R|/A.foo|()
}
public final fun test_7(x: R|kotlin/Any|): R|kotlin/Unit| {
do {
(R|<local>/x| as R|A|)
}
while(Boolean(true))
R|<local>/x|.R|/A.foo|()
}
@@ -0,0 +1,139 @@
digraph multipleCasts_kt {
graph [nodesep=3]
node [shape=box penwidth=2]
edge [penwidth=2]
subgraph cluster_0 {
color=red
0 [label="Enter function foo" style="filled" fillcolor=red];
1 [label="Exit function foo" style="filled" fillcolor=red];
}
0 -> {1};
subgraph cluster_1 {
color=red
2 [label="Enter function foo" style="filled" fillcolor=red];
3 [label="Exit function foo" style="filled" fillcolor=red];
}
2 -> {3};
subgraph cluster_2 {
color=red
4 [label="Enter function getAny" style="filled" fillcolor=red];
5 [label="Const: Null(null)"];
6 [label="Jump: ^getAny Null(null)"];
7 [label="Stub" style="filled" fillcolor=gray];
8 [label="Exit function getAny" style="filled" fillcolor=red];
}
4 -> {5};
5 -> {6};
6 -> {8};
6 -> {7} [style=dotted];
7 -> {8} [style=dotted];
subgraph cluster_3 {
color=red
9 [label="Enter function test_0" style="filled" fillcolor=red];
10 [label="Function call: R|/getAny|()"];
11 [label="Variable declaration: lval a: R|kotlin/Any?|"];
12 [label="Function call: R|/getAny|()"];
13 [label="Variable declaration: lval b: R|kotlin/Any?|"];
14 [label="Access variable R|<local>/a|"];
15 [label="Type operator: (R|<local>/a| as R|A|)"];
16 [label="Access variable R|<local>/a|"];
17 [label="Function call: R|<local>/a|.R|/A.foo|()"];
18 [label="Access variable R|<local>/b|"];
19 [label="Type operator: (R|<local>/b| as R|B|)"];
20 [label="Access variable R|<local>/b|"];
21 [label="Function call: R|<local>/b|.R|/B.foo|()"];
22 [label="Exit function test_0" style="filled" fillcolor=red];
}
9 -> {10};
10 -> {11};
11 -> {12};
12 -> {13};
13 -> {14};
14 -> {15};
15 -> {16};
16 -> {17};
17 -> {18};
18 -> {19};
19 -> {20};
20 -> {21};
21 -> {22};
subgraph cluster_4 {
color=red
23 [label="Enter function test_1" style="filled" fillcolor=red];
24 [label="Function call: R|/getAny|()"];
25 [label="Variable declaration: lval a: R|kotlin/Any?|"];
26 [label="Function call: R|/getAny|()"];
27 [label="Variable declaration: lval b: R|kotlin/Any?|"];
subgraph cluster_5 {
color=blue
28 [label="Enter when"];
subgraph cluster_6 {
color=blue
29 [label="Enter when branch condition "];
subgraph cluster_7 {
color=blue
30 [label="Enter &&"];
31 [label="Access variable R|<local>/a|"];
32 [label="Type operator: (R|<local>/a| is R|A|)"];
33 [label="Exit left part of &&"];
34 [label="Enter right part of &&"];
35 [label="Access variable R|<local>/b|"];
36 [label="Type operator: (R|<local>/b| is R|B|)"];
37 [label="Exit &&"];
}
38 [label="Exit when branch condition"];
}
39 [label="Synthetic else branch"];
40 [label="Enter when branch result"];
subgraph cluster_8 {
color=blue
41 [label="Enter block"];
42 [label="Access variable R|<local>/a|"];
43 [label="Function call: R|<local>/a|.R|/A.foo|()"];
44 [label="Access variable R|<local>/b|"];
45 [label="Function call: R|<local>/b|.R|/B.foo|()"];
46 [label="Exit block"];
}
47 [label="Exit when branch result"];
48 [label="Exit when"];
}
49 [label="Exit function test_1" style="filled" fillcolor=red];
}
23 -> {24};
24 -> {25};
25 -> {26};
26 -> {27};
27 -> {28};
28 -> {29};
29 -> {30};
30 -> {31};
31 -> {32};
32 -> {33};
33 -> {37 34};
34 -> {35};
35 -> {36};
36 -> {37};
37 -> {38};
38 -> {40 39};
39 -> {48};
40 -> {41};
41 -> {42};
42 -> {43};
43 -> {44};
44 -> {45};
45 -> {46};
46 -> {47};
47 -> {48};
48 -> {49};
}
@@ -0,0 +1,29 @@
// !DUMP_CFG
// There would be ambiguities if some expression was smartcasted to (A & B) and foo() was called.
// There was a bug where 2 variables were "bound" together if they are assigned from the same function call or property.
interface A {
fun foo(): Int
}
interface B {
fun foo(): Int
}
fun getAny(): Any? = null
fun test_0() {
val a = getAny()
val b = getAny()
a as A
a.foo()
b as B
b.foo()
}
fun test_1() {
val a = getAny()
val b = getAny()
if (a is A && b is B) {
a.foo()
b.foo()
}
}
@@ -0,0 +1,31 @@
FILE: multipleCasts.kt
public abstract interface A : R|kotlin/Any| {
public abstract fun foo(): R|kotlin/Int|
}
public abstract interface B : R|kotlin/Any| {
public abstract fun foo(): R|kotlin/Int|
}
public final fun getAny(): R|kotlin/Any?| {
^getAny Null(null)
}
public final fun test_0(): R|kotlin/Unit| {
lval a: R|kotlin/Any?| = R|/getAny|()
lval b: R|kotlin/Any?| = R|/getAny|()
(R|<local>/a| as R|A|)
R|<local>/a|.R|/A.foo|()
(R|<local>/b| as R|B|)
R|<local>/b|.R|/B.foo|()
}
public final fun test_1(): R|kotlin/Unit| {
lval a: R|kotlin/Any?| = R|/getAny|()
lval b: R|kotlin/Any?| = R|/getAny|()
when () {
(R|<local>/a| is R|A|) && (R|<local>/b| is R|B|) -> {
R|<local>/a|.R|/A.foo|()
R|<local>/b|.R|/B.foo|()
}
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,177 @@
// !DUMP_CFG
// CONTAINS ERRORS
interface A {
fun foo()
fun getA(): A
}
interface MyData{
val s: Int
fun fs(): Int
}
interface Q {
val data: MyData?
fun fdata(): MyData?
}
class QImpl(override val data: MyData?) : Q {
override fun fdata(): MyData? = null
}
class QImplMutable(override var data: MyData?) : Q {
override fun fdata(): MyData? = null
}
class QImplWithCustomGetter : Q {
override val data: MyData?
get() = null
override fun fdata(): MyData? = null
}
// -------------------------------------------------------------------
fun test_1(x: A?) {
if (x != null) {
x.foo()
} else {
x.<!INAPPLICABLE_CANDIDATE!>foo<!>()
}
x.<!INAPPLICABLE_CANDIDATE!>foo<!>()
}
fun test_2(x: A?) {
if (x == null) {
x.<!INAPPLICABLE_CANDIDATE!>foo<!>()
} else {
x.foo()
}
x.<!INAPPLICABLE_CANDIDATE!>foo<!>()
}
fun test_3(x: A?) {
x ?: return
x.foo()
}
fun test_4(x: A?) {
if (x?.getA() == null) return
x.foo()
}
fun test_5(q: Q?) {
// `q.data` is a property that has an open getter, so we can NOT smartcast it to non-nullable MyData.
if (q?.data?.s?.inc() != null) {
q.data // good
q.data.<!INAPPLICABLE_CANDIDATE!>s<!> // should be bad
q.data.<!INAPPLICABLE_CANDIDATE!>s<!>.<!UNRESOLVED_REFERENCE!>inc<!>() // should be bad
}
}
fun test_6(q: Q?) {
// `q.data` is a property that has an open getter, so we can NOT smartcast it to non-nullable MyData.
q?.data?.s?.inc() ?: return
q.data // good
q.data.<!INAPPLICABLE_CANDIDATE!>s<!> // should be bad
q.data.<!INAPPLICABLE_CANDIDATE!>s<!>.<!UNRESOLVED_REFERENCE!>inc<!>() // should be bad
}
fun test_7(q: Q?) {
if (q?.fdata()?.fs()?.inc() != null) {
q.fdata() // good
q.fdata().<!INAPPLICABLE_CANDIDATE!>fs<!>() // bad
q.fdata().<!INAPPLICABLE_CANDIDATE!>fs<!>().<!UNRESOLVED_REFERENCE!>inc<!>() // bad
}
}
fun test_8(b: Boolean?) {
if (b == true) {
b.not()
}
}
fun test_9(a: Int, b: Int?) {
if (a == b) {
b.inc()
}
b.<!INAPPLICABLE_CANDIDATE!>inc<!>()
if (a === b) {
b.inc()
}
b.<!INAPPLICABLE_CANDIDATE!>inc<!>()
if (b == a) {
b.inc()
}
b.<!INAPPLICABLE_CANDIDATE!>inc<!>()
if (b === a) {
b.inc()
}
b.<!INAPPLICABLE_CANDIDATE!>inc<!>()
}
fun test_10(a: Int?, b: Int?) {
if (a == b) {
b.<!INAPPLICABLE_CANDIDATE!>inc<!>()
}
b.<!INAPPLICABLE_CANDIDATE!>inc<!>()
if (a === b) {
b.<!INAPPLICABLE_CANDIDATE!>inc<!>()
}
b.<!INAPPLICABLE_CANDIDATE!>inc<!>()
if (b == a) {
b.<!INAPPLICABLE_CANDIDATE!>inc<!>()
}
b.<!INAPPLICABLE_CANDIDATE!>inc<!>()
if (b === a) {
b.<!INAPPLICABLE_CANDIDATE!>inc<!>()
}
b.<!INAPPLICABLE_CANDIDATE!>inc<!>()
}
fun test_11(q: QImpl?, q2: QImpl) {
// `q.data` is a property with the default getter, so we CAN smartcast it to non-nullable MyData.
if (q?.data?.s?.inc() != null) {
q.data
q.data.s
q.data.s.inc()
// Smartcasting of `q.data` should have no effect on `q2.data`.
// Issue: Smartcasting of QImpl.data affects all instances
q2.data
q2.data.<!INAPPLICABLE_CANDIDATE!>s<!> // should be bad
q2.data.<!INAPPLICABLE_CANDIDATE!>s<!>.<!UNRESOLVED_REFERENCE!>inc<!>() // should be bad
if (q2.data != null) {
q2.data.s
q2.data.s.inc()
}
}
}
fun test_12(q: QImplWithCustomGetter?) {
// `q.data` is a property that has an open getter, so we can NOT smartcast it to non-nullable MyData.
if (q?.data?.s?.inc() != null) {
q.data // good
q.data.<!INAPPLICABLE_CANDIDATE!>s<!> // should be bad
q.data.<!INAPPLICABLE_CANDIDATE!>s<!>.<!UNRESOLVED_REFERENCE!>inc<!>() // should be bad
}
}
fun test_13(q: QImplMutable?) {
// `q.data` is a property that is mutable, so we can NOT smartcast it to non-nullable MyData.
if (q?.data?.s?.inc() != null) {
q.data // good
q.data.<!INAPPLICABLE_CANDIDATE!>s<!> // should be bad
q.data.<!INAPPLICABLE_CANDIDATE!>s<!>.<!UNRESOLVED_REFERENCE!>inc<!>() // should be bad
}
}
@@ -0,0 +1,250 @@
FILE: nullability.kt
public abstract interface A : R|kotlin/Any| {
public abstract fun foo(): R|kotlin/Unit|
public abstract fun getA(): R|A|
}
public abstract interface MyData : R|kotlin/Any| {
public abstract val s: R|kotlin/Int|
public get(): R|kotlin/Int|
public abstract fun fs(): R|kotlin/Int|
}
public abstract interface Q : R|kotlin/Any| {
public abstract val data: R|MyData?|
public get(): R|MyData?|
public abstract fun fdata(): R|MyData?|
}
public final class QImpl : R|Q| {
public constructor(data: R|MyData?|): R|QImpl| {
super<R|kotlin/Any|>()
}
public final override val data: R|MyData?| = R|<local>/data|
public get(): R|MyData?|
public final override fun fdata(): R|MyData?| {
^fdata Null(null)
}
}
public final class QImplMutable : R|Q| {
public constructor(data: R|MyData?|): R|QImplMutable| {
super<R|kotlin/Any|>()
}
public final override var data: R|MyData?| = R|<local>/data|
public get(): R|MyData?|
public set(value: R|MyData?|): R|kotlin/Unit|
public final override fun fdata(): R|MyData?| {
^fdata Null(null)
}
}
public final class QImplWithCustomGetter : R|Q| {
public constructor(): R|QImplWithCustomGetter| {
super<R|kotlin/Any|>()
}
public final override val data: R|MyData?|
public get(): R|MyData?| {
^ Null(null)
}
public final override fun fdata(): R|MyData?| {
^fdata Null(null)
}
}
public final fun test_1(x: R|A?|): R|kotlin/Unit| {
when () {
!=(R|<local>/x|, Null(null)) -> {
R|<local>/x|.R|/A.foo|()
}
else -> {
R|<local>/x|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()
}
}
R|<local>/x|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()
}
public final fun test_2(x: R|A?|): R|kotlin/Unit| {
when () {
==(R|<local>/x|, Null(null)) -> {
R|<local>/x|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()
}
else -> {
R|<local>/x|.R|/A.foo|()
}
}
R|<local>/x|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()
}
public final fun test_3(x: R|A?|): R|kotlin/Unit| {
when (lval <elvis>: R|A?| = R|<local>/x|) {
==($subj$, Null(null)) -> {
^test_3 Unit
}
else -> {
R|<local>/<elvis>|
}
}
R|<local>/x|.R|/A.foo|()
}
public final fun test_4(x: R|A?|): R|kotlin/Unit| {
when () {
==(R|<local>/x|?.R|/A.getA|(), Null(null)) -> {
^test_4 Unit
}
}
R|<local>/x|.R|/A.foo|()
}
public final fun test_5(q: R|Q?|): R|kotlin/Unit| {
when () {
!=(R|<local>/q|?.R|/Q.data|?.R|/MyData.s|?.R|kotlin/Int.inc|(), Null(null)) -> {
R|<local>/q|.R|/Q.data|
R|<local>/q|.R|/Q.data|.<Inapplicable(WRONG_RECEIVER): [/MyData.s]>#
R|<local>/q|.R|/Q.data|.<Inapplicable(WRONG_RECEIVER): [/MyData.s]>#.<Unresolved name: inc>#()
}
}
}
public final fun test_6(q: R|Q?|): R|kotlin/Unit| {
when (lval <elvis>: R|kotlin/Int?| = R|<local>/q|?.R|/Q.data|?.R|/MyData.s|?.R|kotlin/Int.inc|()) {
==($subj$, Null(null)) -> {
^test_6 Unit
}
else -> {
R|<local>/<elvis>|
}
}
R|<local>/q|.R|/Q.data|
R|<local>/q|.R|/Q.data|.<Inapplicable(WRONG_RECEIVER): [/MyData.s]>#
R|<local>/q|.R|/Q.data|.<Inapplicable(WRONG_RECEIVER): [/MyData.s]>#.<Unresolved name: inc>#()
}
public final fun test_7(q: R|Q?|): R|kotlin/Unit| {
when () {
!=(R|<local>/q|?.R|/Q.fdata|()?.R|/MyData.fs|()?.R|kotlin/Int.inc|(), Null(null)) -> {
R|<local>/q|.R|/Q.fdata|()
R|<local>/q|.R|/Q.fdata|().<Inapplicable(WRONG_RECEIVER): [/MyData.fs]>#()
R|<local>/q|.R|/Q.fdata|().<Inapplicable(WRONG_RECEIVER): [/MyData.fs]>#().<Unresolved name: inc>#()
}
}
}
public final fun test_8(b: R|kotlin/Boolean?|): R|kotlin/Unit| {
when () {
==(R|<local>/b|, Boolean(true)) -> {
R|<local>/b|.R|kotlin/Boolean.not|()
}
}
}
public final fun test_9(a: R|kotlin/Int|, b: R|kotlin/Int?|): R|kotlin/Unit| {
when () {
==(R|<local>/a|, R|<local>/b|) -> {
R|<local>/b|.R|kotlin/Int.inc|()
}
}
R|<local>/b|.<Inapplicable(WRONG_RECEIVER): [kotlin/Int.inc]>#()
when () {
===(R|<local>/a|, R|<local>/b|) -> {
R|<local>/b|.R|kotlin/Int.inc|()
}
}
R|<local>/b|.<Inapplicable(WRONG_RECEIVER): [kotlin/Int.inc]>#()
when () {
==(R|<local>/b|, R|<local>/a|) -> {
R|<local>/b|.R|kotlin/Int.inc|()
}
}
R|<local>/b|.<Inapplicable(WRONG_RECEIVER): [kotlin/Int.inc]>#()
when () {
===(R|<local>/b|, R|<local>/a|) -> {
R|<local>/b|.R|kotlin/Int.inc|()
}
}
R|<local>/b|.<Inapplicable(WRONG_RECEIVER): [kotlin/Int.inc]>#()
}
public final fun test_10(a: R|kotlin/Int?|, b: R|kotlin/Int?|): R|kotlin/Unit| {
when () {
==(R|<local>/a|, R|<local>/b|) -> {
R|<local>/b|.<Inapplicable(WRONG_RECEIVER): [kotlin/Int.inc]>#()
}
}
R|<local>/b|.<Inapplicable(WRONG_RECEIVER): [kotlin/Int.inc]>#()
when () {
===(R|<local>/a|, R|<local>/b|) -> {
R|<local>/b|.<Inapplicable(WRONG_RECEIVER): [kotlin/Int.inc]>#()
}
}
R|<local>/b|.<Inapplicable(WRONG_RECEIVER): [kotlin/Int.inc]>#()
when () {
==(R|<local>/b|, R|<local>/a|) -> {
R|<local>/b|.<Inapplicable(WRONG_RECEIVER): [kotlin/Int.inc]>#()
}
}
R|<local>/b|.<Inapplicable(WRONG_RECEIVER): [kotlin/Int.inc]>#()
when () {
===(R|<local>/b|, R|<local>/a|) -> {
R|<local>/b|.<Inapplicable(WRONG_RECEIVER): [kotlin/Int.inc]>#()
}
}
R|<local>/b|.<Inapplicable(WRONG_RECEIVER): [kotlin/Int.inc]>#()
}
public final fun test_11(q: R|QImpl?|, q2: R|QImpl|): R|kotlin/Unit| {
when () {
!=(R|<local>/q|?.R|/QImpl.data|?.R|/MyData.s|?.R|kotlin/Int.inc|(), Null(null)) -> {
R|<local>/q|.R|/QImpl.data|
R|<local>/q|.R|/QImpl.data|.R|/MyData.s|
R|<local>/q|.R|/QImpl.data|.R|/MyData.s|.R|kotlin/Int.inc|()
R|<local>/q2|.R|/QImpl.data|
R|<local>/q2|.R|/QImpl.data|.<Inapplicable(WRONG_RECEIVER): [/MyData.s]>#
R|<local>/q2|.R|/QImpl.data|.<Inapplicable(WRONG_RECEIVER): [/MyData.s]>#.<Unresolved name: inc>#()
when () {
!=(R|<local>/q2|.R|/QImpl.data|, Null(null)) -> {
R|<local>/q2|.R|/QImpl.data|.R|/MyData.s|
R|<local>/q2|.R|/QImpl.data|.R|/MyData.s|.R|kotlin/Int.inc|()
}
}
}
}
}
public final fun test_12(q: R|QImplWithCustomGetter?|): R|kotlin/Unit| {
when () {
!=(R|<local>/q|?.R|/QImplWithCustomGetter.data|?.R|/MyData.s|?.R|kotlin/Int.inc|(), Null(null)) -> {
R|<local>/q|.R|/QImplWithCustomGetter.data|
R|<local>/q|.R|/QImplWithCustomGetter.data|.<Inapplicable(WRONG_RECEIVER): [/MyData.s]>#
R|<local>/q|.R|/QImplWithCustomGetter.data|.<Inapplicable(WRONG_RECEIVER): [/MyData.s]>#.<Unresolved name: inc>#()
}
}
}
public final fun test_13(q: R|QImplMutable?|): R|kotlin/Unit| {
when () {
!=(R|<local>/q|?.R|/QImplMutable.data|?.R|/MyData.s|?.R|kotlin/Int.inc|(), Null(null)) -> {
R|<local>/q|.R|/QImplMutable.data|
R|<local>/q|.R|/QImplMutable.data|.<Inapplicable(WRONG_RECEIVER): [/MyData.s]>#
R|<local>/q|.R|/QImplMutable.data|.<Inapplicable(WRONG_RECEIVER): [/MyData.s]>#.<Unresolved name: inc>#()
}
}
}
@@ -0,0 +1,27 @@
// ISSUE: KT-36057
fun String.foo() {}
fun test_1(a: Any?) {
when (a) {
is String, is Any -> a.<!INAPPLICABLE_CANDIDATE!>foo<!>() // Should be Bad
}
}
fun test_2(a: Any?) {
if (a is String || a is Any) {
a.<!INAPPLICABLE_CANDIDATE!>foo<!>() // Should be Bad
}
}
fun test_3(a: Any?, b: Boolean) {
when (a) {
is String, b -> a.<!INAPPLICABLE_CANDIDATE!>foo<!>() // Should be Bad
}
}
fun test_4(a: Any?, b: Boolean) {
if (a is String || b) {
a.<!INAPPLICABLE_CANDIDATE!>foo<!>() // Should be Bad
}
}
@@ -0,0 +1,35 @@
FILE: orInWhenBranch.kt
public final fun R|kotlin/String|.foo(): R|kotlin/Unit| {
}
public final fun test_1(a: R|kotlin/Any?|): R|kotlin/Unit| {
when (R|<local>/a|) {
($subj$ is R|kotlin/String|) || ($subj$ is R|kotlin/Any|) -> {
R|<local>/a|.<Inapplicable(WRONG_RECEIVER): [/foo]>#()
}
}
}
public final fun test_2(a: R|kotlin/Any?|): R|kotlin/Unit| {
when () {
(R|<local>/a| is R|kotlin/String|) || (R|<local>/a| is R|kotlin/Any|) -> {
R|<local>/a|.<Inapplicable(WRONG_RECEIVER): [/foo]>#()
}
}
}
public final fun test_3(a: R|kotlin/Any?|, b: R|kotlin/Boolean|): R|kotlin/Unit| {
when (R|<local>/a|) {
($subj$ is R|kotlin/String|) || ==($subj$, R|<local>/b|) -> {
R|<local>/a|.<Inapplicable(WRONG_RECEIVER): [/foo]>#()
}
}
}
public final fun test_4(a: R|kotlin/Any?|, b: R|kotlin/Boolean|): R|kotlin/Unit| {
when () {
(R|<local>/a| is R|kotlin/String|) || R|<local>/b| -> {
R|<local>/a|.<Inapplicable(WRONG_RECEIVER): [/foo]>#()
}
}
}
@@ -0,0 +1,9 @@
fun Any.withInvoke(f: String.() -> Unit) {
if (this is String) {
f() // Should be OK
}
}
fun String.withInvoke(f: String.() -> Unit) {
f()
}
@@ -0,0 +1,12 @@
FILE: invoke.kt
public final fun R|kotlin/Any|.withInvoke(f: R|kotlin/String.() -> kotlin/Unit|): R|kotlin/Unit| {
when () {
(this@R|/withInvoke| is R|kotlin/String|) -> {
R|<local>/f|.R|FakeOverride<kotlin/Function1.invoke: R|kotlin/Unit|>|(this@R|/withInvoke|)
}
}
}
public final fun R|kotlin/String|.withInvoke(f: R|kotlin/String.() -> kotlin/Unit|): R|kotlin/Unit| {
R|<local>/f|.R|FakeOverride<kotlin/Function1.invoke: R|kotlin/Unit|>|(this@R|/withInvoke|)
}
@@ -0,0 +1,216 @@
digraph implicitReceiverAsWhenSubject_kt {
graph [nodesep=3]
node [shape=box penwidth=2]
edge [penwidth=2]
subgraph cluster_0 {
color=red
0 [label="Enter function test_1" style="filled" fillcolor=red];
subgraph cluster_1 {
color=blue
1 [label="Enter when"];
2 [label="Access variable this@R|/test_1|"];
subgraph cluster_2 {
color=blue
3 [label="Enter when branch condition "];
4 [label="Type operator: ($subj$ is R|kotlin/collections/List<*>|)"];
5 [label="Exit when branch condition"];
}
subgraph cluster_3 {
color=blue
6 [label="Enter when branch condition "];
7 [label="Type operator: ($subj$ is R|kotlin/String|)"];
8 [label="Exit when branch condition"];
}
subgraph cluster_4 {
color=blue
9 [label="Enter when branch condition else"];
10 [label="Exit when branch condition"];
}
11 [label="Enter when branch result"];
subgraph cluster_5 {
color=blue
12 [label="Enter block"];
13 [label="Const: Int(0)"];
14 [label="Exit block"];
}
15 [label="Exit when branch result"];
16 [label="Enter when branch result"];
subgraph cluster_6 {
color=blue
17 [label="Enter block"];
18 [label="Access variable R|kotlin/String.length|"];
19 [label="Exit block"];
}
20 [label="Exit when branch result"];
21 [label="Enter when branch result"];
subgraph cluster_7 {
color=blue
22 [label="Enter block"];
23 [label="Access variable this@R|/test_1|"];
24 [label="Access variable R|kotlin/collections/List.size|"];
25 [label="Exit block"];
}
26 [label="Exit when branch result"];
27 [label="Exit when"];
}
28 [label="Jump: ^test_1 when (this@R|/test_1|) {
($subj$ is R|kotlin/collections/List<*>|) -> {
this@R|/test_1|.R|kotlin/collections/List.size|
}
($subj$ is R|kotlin/String|) -> {
this@R|/test_1|.R|kotlin/String.length|
}
else -> {
Int(0)
}
}
"];
29 [label="Stub" style="filled" fillcolor=gray];
30 [label="Exit function test_1" style="filled" fillcolor=red];
}
0 -> {1};
1 -> {2};
2 -> {3};
3 -> {4};
4 -> {5};
5 -> {21 6};
6 -> {7};
7 -> {8};
8 -> {16 9};
9 -> {10};
10 -> {11};
11 -> {12};
12 -> {13};
13 -> {14};
14 -> {15};
15 -> {27};
16 -> {17};
17 -> {18};
18 -> {19};
19 -> {20};
20 -> {27};
21 -> {22};
22 -> {23};
23 -> {24};
24 -> {25};
25 -> {26};
26 -> {27};
27 -> {28};
28 -> {30};
28 -> {29} [style=dotted];
29 -> {30} [style=dotted];
subgraph cluster_8 {
color=red
31 [label="Enter function test_2" style="filled" fillcolor=red];
subgraph cluster_9 {
color=blue
32 [label="Enter when"];
33 [label="Access variable this@R|/test_2|"];
34 [label="Variable declaration: lval x: R|kotlin/Any|"];
subgraph cluster_10 {
color=blue
35 [label="Enter when branch condition "];
36 [label="Type operator: ($subj$ is R|kotlin/collections/List<*>|)"];
37 [label="Exit when branch condition"];
}
subgraph cluster_11 {
color=blue
38 [label="Enter when branch condition "];
39 [label="Type operator: ($subj$ is R|kotlin/String|)"];
40 [label="Exit when branch condition"];
}
subgraph cluster_12 {
color=blue
41 [label="Enter when branch condition else"];
42 [label="Exit when branch condition"];
}
43 [label="Enter when branch result"];
subgraph cluster_13 {
color=blue
44 [label="Enter block"];
45 [label="Const: Int(0)"];
46 [label="Exit block"];
}
47 [label="Exit when branch result"];
48 [label="Enter when branch result"];
subgraph cluster_14 {
color=blue
49 [label="Enter block"];
50 [label="Access variable R|<local>/x|"];
51 [label="Access variable R|kotlin/String.length|"];
52 [label="Access variable R|kotlin/String.length|"];
53 [label="Exit block"];
}
54 [label="Exit when branch result"];
55 [label="Enter when branch result"];
subgraph cluster_15 {
color=blue
56 [label="Enter block"];
57 [label="Access variable R|<local>/x|"];
58 [label="Access variable R|kotlin/collections/List.size|"];
59 [label="Access variable this@R|/test_2|"];
60 [label="Access variable R|kotlin/collections/List.size|"];
61 [label="Exit block"];
}
62 [label="Exit when branch result"];
63 [label="Exit when"];
}
64 [label="Jump: ^test_2 when (lval x: R|kotlin/Any| = this@R|/test_2|) {
($subj$ is R|kotlin/collections/List<*>|) -> {
R|<local>/x|.R|kotlin/collections/List.size|
this@R|/test_2|.R|kotlin/collections/List.size|
}
($subj$ is R|kotlin/String|) -> {
R|<local>/x|.R|kotlin/String.length|
this@R|/test_2|.R|kotlin/String.length|
}
else -> {
Int(0)
}
}
"];
65 [label="Stub" style="filled" fillcolor=gray];
66 [label="Exit function test_2" style="filled" fillcolor=red];
}
31 -> {32};
32 -> {33};
33 -> {34};
34 -> {35};
35 -> {36};
36 -> {37};
37 -> {55 38};
38 -> {39};
39 -> {40};
40 -> {48 41};
41 -> {42};
42 -> {43};
43 -> {44};
44 -> {45};
45 -> {46};
46 -> {47};
47 -> {63};
48 -> {49};
49 -> {50};
50 -> {51};
51 -> {52};
52 -> {53};
53 -> {54};
54 -> {63};
55 -> {56};
56 -> {57};
57 -> {58};
58 -> {59};
59 -> {60};
60 -> {61};
61 -> {62};
62 -> {63};
63 -> {64};
64 -> {66};
64 -> {65} [style=dotted];
65 -> {66} [style=dotted];
}
@@ -0,0 +1,18 @@
// !DUMP_CFG
fun Any.test_1(): Int = when (this) {
is List<*> -> this.size
is String -> length
else -> 0
}
fun Any.test_2(): Int = when (val x = this) {
is List<*> -> {
x.size
this.size
}
is String -> {
x.length
length
}
else -> 0
}
@@ -0,0 +1,31 @@
FILE: implicitReceiverAsWhenSubject.kt
public final fun R|kotlin/Any|.test_1(): R|kotlin/Int| {
^test_1 when (this@R|/test_1|) {
($subj$ is R|kotlin/collections/List<*>|) -> {
this@R|/test_1|.R|kotlin/collections/List.size|
}
($subj$ is R|kotlin/String|) -> {
this@R|/test_1|.R|kotlin/String.length|
}
else -> {
Int(0)
}
}
}
public final fun R|kotlin/Any|.test_2(): R|kotlin/Int| {
^test_2 when (lval x: R|kotlin/Any| = this@R|/test_2|) {
($subj$ is R|kotlin/collections/List<*>|) -> {
R|<local>/x|.R|kotlin/collections/List.size|
this@R|/test_2|.R|kotlin/collections/List.size|
}
($subj$ is R|kotlin/String|) -> {
R|<local>/x|.R|kotlin/String.length|
this@R|/test_2|.R|kotlin/String.length|
}
else -> {
Int(0)
}
}
}
@@ -0,0 +1,544 @@
digraph implicitReceivers_kt {
graph [nodesep=3]
node [shape=box penwidth=2]
edge [penwidth=2]
subgraph cluster_0 {
color=red
0 [label="Enter function <init>" style="filled" fillcolor=red];
1 [label="Delegated constructor call: super<R|kotlin/Any|>()"];
2 [label="Exit function <init>" style="filled" fillcolor=red];
}
0 -> {1};
1 -> {2};
subgraph cluster_1 {
color=red
3 [label="Enter function foo" style="filled" fillcolor=red];
4 [label="Exit function foo" style="filled" fillcolor=red];
}
3 -> {4};
subgraph cluster_2 {
color=red
5 [label="Enter function <init>" style="filled" fillcolor=red];
6 [label="Delegated constructor call: super<R|kotlin/Any|>()"];
7 [label="Exit function <init>" style="filled" fillcolor=red];
}
5 -> {6};
6 -> {7};
subgraph cluster_3 {
color=red
8 [label="Enter function bar" style="filled" fillcolor=red];
9 [label="Exit function bar" style="filled" fillcolor=red];
}
8 -> {9};
subgraph cluster_4 {
color=red
10 [label="Enter function with" style="filled" fillcolor=red];
11 [label="Exit function with" style="filled" fillcolor=red];
}
10 -> {11};
subgraph cluster_5 {
color=red
12 [label="Enter function test_1" style="filled" fillcolor=red];
subgraph cluster_6 {
color=blue
13 [label="Enter when"];
subgraph cluster_7 {
color=blue
14 [label="Enter when branch condition "];
15 [label="Access variable this@R|/test_1|"];
16 [label="Type operator: (this@R|/test_1| is R|A|)"];
17 [label="Exit when branch condition"];
}
subgraph cluster_8 {
color=blue
18 [label="Enter when branch condition else"];
19 [label="Exit when branch condition"];
}
20 [label="Enter when branch result"];
subgraph cluster_9 {
color=blue
21 [label="Enter block"];
22 [label="Access variable this@R|/test_1|"];
23 [label="Function call: this@R|/test_1|.<Unresolved name: foo>#()"];
24 [label="Function call: <Unresolved name: foo>#()"];
25 [label="Exit block"];
}
26 [label="Exit when branch result"];
27 [label="Enter when branch result"];
subgraph cluster_10 {
color=blue
28 [label="Enter block"];
29 [label="Access variable this@R|/test_1|"];
30 [label="Function call: this@R|/test_1|.R|/A.foo|()"];
31 [label="Function call: this@R|/test_1|.R|/A.foo|()"];
32 [label="Exit block"];
}
33 [label="Exit when branch result"];
34 [label="Exit when"];
}
35 [label="Access variable this@R|/test_1|"];
36 [label="Function call: this@R|/test_1|.<Unresolved name: foo>#()"];
37 [label="Function call: <Unresolved name: foo>#()"];
38 [label="Exit function test_1" style="filled" fillcolor=red];
}
12 -> {13};
13 -> {14};
14 -> {15};
15 -> {16};
16 -> {17};
17 -> {27 18};
18 -> {19};
19 -> {20};
20 -> {21};
21 -> {22};
22 -> {23};
23 -> {24};
24 -> {25};
25 -> {26};
26 -> {34};
27 -> {28};
28 -> {29};
29 -> {30};
30 -> {31};
31 -> {32};
32 -> {33};
33 -> {34};
34 -> {35};
35 -> {36};
36 -> {37};
37 -> {38};
subgraph cluster_11 {
color=red
39 [label="Enter function test_2" style="filled" fillcolor=red];
subgraph cluster_12 {
color=blue
40 [label="Enter when"];
subgraph cluster_13 {
color=blue
41 [label="Enter when branch condition "];
42 [label="Access variable this@R|/test_2|"];
43 [label="Type operator: (this@R|/test_2| !is R|A|)"];
44 [label="Exit when branch condition"];
}
subgraph cluster_14 {
color=blue
45 [label="Enter when branch condition else"];
46 [label="Exit when branch condition"];
}
47 [label="Enter when branch result"];
subgraph cluster_15 {
color=blue
48 [label="Enter block"];
49 [label="Access variable this@R|/test_2|"];
50 [label="Function call: this@R|/test_2|.R|/A.foo|()"];
51 [label="Function call: this@R|/test_2|.R|/A.foo|()"];
52 [label="Exit block"];
}
53 [label="Exit when branch result"];
54 [label="Enter when branch result"];
subgraph cluster_16 {
color=blue
55 [label="Enter block"];
56 [label="Access variable this@R|/test_2|"];
57 [label="Function call: this@R|/test_2|.<Unresolved name: foo>#()"];
58 [label="Function call: <Unresolved name: foo>#()"];
59 [label="Exit block"];
}
60 [label="Exit when branch result"];
61 [label="Exit when"];
}
62 [label="Access variable this@R|/test_2|"];
63 [label="Function call: this@R|/test_2|.<Unresolved name: foo>#()"];
64 [label="Function call: <Unresolved name: foo>#()"];
65 [label="Exit function test_2" style="filled" fillcolor=red];
}
39 -> {40};
40 -> {41};
41 -> {42};
42 -> {43};
43 -> {44};
44 -> {54 45};
45 -> {46};
46 -> {47};
47 -> {48};
48 -> {49};
49 -> {50};
50 -> {51};
51 -> {52};
52 -> {53};
53 -> {61};
54 -> {55};
55 -> {56};
56 -> {57};
57 -> {58};
58 -> {59};
59 -> {60};
60 -> {61};
61 -> {62};
62 -> {63};
63 -> {64};
64 -> {65};
subgraph cluster_17 {
color=red
66 [label="Enter function test_3" style="filled" fillcolor=red];
67 [label="Access variable R|<local>/a|"];
68 [label="Postponed enter to lambda"];
subgraph cluster_18 {
color=blue
69 [label="Enter function anonymousFunction"];
70 [label="Access variable R|<local>/b|"];
71 [label="Postponed enter to lambda"];
subgraph cluster_19 {
color=blue
72 [label="Enter function anonymousFunction"];
73 [label="Access variable R|<local>/c|"];
74 [label="Postponed enter to lambda"];
subgraph cluster_20 {
color=blue
75 [label="Enter function anonymousFunction"];
76 [label="Access variable this@R|special/anonymous|"];
77 [label="Type operator: (this@R|special/anonymous| as R|A|)"];
78 [label="Access variable this@R|special/anonymous|"];
79 [label="Function call: this@R|special/anonymous|.R|/A.foo|()"];
80 [label="Function call: this@R|special/anonymous|.R|/A.foo|()"];
81 [label="Exit function anonymousFunction"];
}
82 [label="Call arguments union" style="filled" fillcolor=yellow];
83 [label="Postponed exit from lambda"];
84 [label="Function call: R|kotlin/with|<R|kotlin/Any|, R|kotlin/Unit|>(...)"];
85 [label="Access variable this@R|special/anonymous|"];
86 [label="Function call: this@R|special/anonymous|.R|/A.foo|()"];
87 [label="Function call: this@R|special/anonymous|.R|/A.foo|()"];
88 [label="Exit function anonymousFunction"];
}
89 [label="Postponed exit from lambda"];
90 [label="Function call: R|kotlin/with|<R|kotlin/Any|, R|kotlin/Unit|>(...)"];
91 [label="Exit function anonymousFunction"];
}
92 [label="Call arguments union" style="filled" fillcolor=yellow];
93 [label="Postponed exit from lambda"];
94 [label="Function call: R|kotlin/with|<R|kotlin/Any|, R|kotlin/Unit|>(...)"];
95 [label="Exit function test_3" style="filled" fillcolor=red];
}
66 -> {67};
67 -> {68};
68 -> {69};
68 -> {93} [color=red];
69 -> {70};
70 -> {71};
71 -> {72};
71 -> {89} [color=red];
72 -> {73};
73 -> {74};
74 -> {75};
74 -> {83} [color=red];
75 -> {76};
76 -> {77};
77 -> {78};
78 -> {79};
79 -> {80};
80 -> {81};
81 -> {83} [color=green];
81 -> {82} [color=red];
82 -> {84} [color=red];
83 -> {84} [color=green];
84 -> {85};
85 -> {86};
86 -> {87};
87 -> {88};
88 -> {89} [color=green];
88 -> {92} [color=red];
89 -> {90};
90 -> {91};
91 -> {93} [color=green];
91 -> {92} [color=red];
92 -> {94} [color=red];
93 -> {94} [color=green];
94 -> {95};
subgraph cluster_21 {
color=red
96 [label="Enter function test_4" style="filled" fillcolor=red];
subgraph cluster_22 {
color=blue
97 [label="Enter when"];
subgraph cluster_23 {
color=blue
98 [label="Enter when branch condition "];
99 [label="Access variable this@R|/test_4|"];
100 [label="Type operator: (this@R|/test_4| !is R|A|)"];
101 [label="Exit when branch condition"];
}
subgraph cluster_24 {
color=blue
102 [label="Enter when branch condition else"];
103 [label="Exit when branch condition"];
}
104 [label="Enter when branch result"];
subgraph cluster_25 {
color=blue
105 [label="Enter block"];
subgraph cluster_26 {
color=blue
106 [label="Enter when"];
subgraph cluster_27 {
color=blue
107 [label="Enter when branch condition "];
108 [label="Access variable this@R|/test_4|"];
109 [label="Type operator: (this@R|/test_4| !is R|B|)"];
110 [label="Exit when branch condition"];
}
subgraph cluster_28 {
color=blue
111 [label="Enter when branch condition else"];
112 [label="Exit when branch condition"];
}
113 [label="Enter when branch result"];
subgraph cluster_29 {
color=blue
114 [label="Enter block"];
115 [label="Access variable this@R|/test_4|"];
116 [label="Function call: this@R|/test_4|.R|/A.foo|()"];
117 [label="Function call: this@R|/test_4|.R|/A.foo|()"];
118 [label="Access variable this@R|/test_4|"];
119 [label="Function call: this@R|/test_4|.R|/B.bar|()"];
120 [label="Function call: this@R|/test_4|.R|/B.bar|()"];
121 [label="Exit block"];
}
122 [label="Exit when branch result"];
123 [label="Enter when branch result"];
subgraph cluster_30 {
color=blue
124 [label="Enter block"];
125 [label="Access variable this@R|/test_4|"];
126 [label="Function call: this@R|/test_4|.<Unresolved name: bar>#()"];
127 [label="Function call: <Unresolved name: bar>#()"];
128 [label="Access variable this@R|/test_4|"];
129 [label="Function call: this@R|/test_4|.R|/A.foo|()"];
130 [label="Function call: this@R|/test_4|.R|/A.foo|()"];
131 [label="Exit block"];
}
132 [label="Exit when branch result"];
133 [label="Exit when"];
}
134 [label="Exit block"];
}
135 [label="Exit when branch result"];
136 [label="Enter when branch result"];
subgraph cluster_31 {
color=blue
137 [label="Enter block"];
138 [label="Access variable this@R|/test_4|"];
139 [label="Function call: this@R|/test_4|.<Unresolved name: foo>#()"];
140 [label="Function call: <Unresolved name: foo>#()"];
141 [label="Access variable this@R|/test_4|"];
142 [label="Function call: this@R|/test_4|.<Unresolved name: bar>#()"];
143 [label="Function call: <Unresolved name: bar>#()"];
144 [label="Exit block"];
}
145 [label="Exit when branch result"];
146 [label="Exit when"];
}
147 [label="Access variable this@R|/test_4|"];
148 [label="Function call: this@R|/test_4|.<Unresolved name: foo>#()"];
149 [label="Function call: <Unresolved name: foo>#()"];
150 [label="Access variable this@R|/test_4|"];
151 [label="Function call: this@R|/test_4|.<Unresolved name: bar>#()"];
152 [label="Function call: <Unresolved name: bar>#()"];
153 [label="Exit function test_4" style="filled" fillcolor=red];
}
96 -> {97};
97 -> {98};
98 -> {99};
99 -> {100};
100 -> {101};
101 -> {136 102};
102 -> {103};
103 -> {104};
104 -> {105};
105 -> {106};
106 -> {107};
107 -> {108};
108 -> {109};
109 -> {110};
110 -> {123 111};
111 -> {112};
112 -> {113};
113 -> {114};
114 -> {115};
115 -> {116};
116 -> {117};
117 -> {118};
118 -> {119};
119 -> {120};
120 -> {121};
121 -> {122};
122 -> {133};
123 -> {124};
124 -> {125};
125 -> {126};
126 -> {127};
127 -> {128};
128 -> {129};
129 -> {130};
130 -> {131};
131 -> {132};
132 -> {133};
133 -> {134};
134 -> {135};
135 -> {146};
136 -> {137};
137 -> {138};
138 -> {139};
139 -> {140};
140 -> {141};
141 -> {142};
142 -> {143};
143 -> {144};
144 -> {145};
145 -> {146};
146 -> {147};
147 -> {148};
148 -> {149};
149 -> {150};
150 -> {151};
151 -> {152};
152 -> {153};
subgraph cluster_32 {
color=red
154 [label="Enter function test_5" style="filled" fillcolor=red];
subgraph cluster_33 {
color=blue
155 [label="Enter when"];
subgraph cluster_34 {
color=blue
156 [label="Enter when branch condition "];
157 [label="Access variable this@R|/test_5|"];
158 [label="Type operator: (this@R|/test_5| is R|kotlin/collections/List<*>|)"];
159 [label="Exit when branch condition"];
}
subgraph cluster_35 {
color=blue
160 [label="Enter when branch condition "];
161 [label="Access variable this@R|/test_5|"];
162 [label="Type operator: (this@R|/test_5| is R|kotlin/String|)"];
163 [label="Exit when branch condition"];
}
subgraph cluster_36 {
color=blue
164 [label="Enter when branch condition else"];
165 [label="Exit when branch condition"];
}
166 [label="Enter when branch result"];
subgraph cluster_37 {
color=blue
167 [label="Enter block"];
168 [label="Const: Int(0)"];
169 [label="Exit block"];
}
170 [label="Exit when branch result"];
171 [label="Enter when branch result"];
subgraph cluster_38 {
color=blue
172 [label="Enter block"];
173 [label="Access variable R|kotlin/String.length|"];
174 [label="Exit block"];
}
175 [label="Exit when branch result"];
176 [label="Enter when branch result"];
subgraph cluster_39 {
color=blue
177 [label="Enter block"];
178 [label="Access variable R|kotlin/collections/List.size|"];
179 [label="Exit block"];
}
180 [label="Exit when branch result"];
181 [label="Exit when"];
}
182 [label="Jump: ^test_5 when () {
(this@R|/test_5| is R|kotlin/collections/List<*>|) -> {
this@R|/test_5|.R|kotlin/collections/List.size|
}
(this@R|/test_5| is R|kotlin/String|) -> {
this@R|/test_5|.R|kotlin/String.length|
}
else -> {
Int(0)
}
}
"];
183 [label="Stub" style="filled" fillcolor=gray];
184 [label="Exit function test_5" style="filled" fillcolor=red];
}
154 -> {155};
155 -> {156};
156 -> {157};
157 -> {158};
158 -> {159};
159 -> {176 160};
160 -> {161};
161 -> {162};
162 -> {163};
163 -> {171 164};
164 -> {165};
165 -> {166};
166 -> {167};
167 -> {168};
168 -> {169};
169 -> {170};
170 -> {181};
171 -> {172};
172 -> {173};
173 -> {174};
174 -> {175};
175 -> {181};
176 -> {177};
177 -> {178};
178 -> {179};
179 -> {180};
180 -> {181};
181 -> {182};
182 -> {184};
182 -> {183} [style=dotted];
183 -> {184} [style=dotted];
subgraph cluster_40 {
color=red
185 [label="Enter function test_6" style="filled" fillcolor=red];
186 [label="Access variable this@R|/test_6|"];
187 [label="Type operator: (this@R|/test_6| as R|kotlin/collections/List<*>|)"];
188 [label="Access variable R|kotlin/collections/List.size|"];
189 [label="Access variable this@R|/test_6|"];
190 [label="Type operator: (this@R|/test_6| as R|kotlin/String|)"];
191 [label="Access variable R|kotlin/String.length|"];
192 [label="Exit function test_6" style="filled" fillcolor=red];
}
185 -> {186};
186 -> {187};
187 -> {188};
188 -> {189};
189 -> {190};
190 -> {191};
191 -> {192};
}
@@ -0,0 +1,84 @@
// !DUMP_CFG
class A {
fun foo() {}
}
class B {
fun bar() {}
}
fun <T> T.with(block: T.() -> Unit) {}
fun Any?.test_1() {
if (this is A) {
this.foo()
foo()
} else {
this.<!UNRESOLVED_REFERENCE!>foo<!>()
<!UNRESOLVED_REFERENCE!>foo<!>()
}
this.<!UNRESOLVED_REFERENCE!>foo<!>()
<!UNRESOLVED_REFERENCE!>foo<!>()
}
fun Any?.test_2() {
if (this !is A) {
this.<!UNRESOLVED_REFERENCE!>foo<!>()
<!UNRESOLVED_REFERENCE!>foo<!>()
} else {
this.foo()
foo()
}
this.<!UNRESOLVED_REFERENCE!>foo<!>()
<!UNRESOLVED_REFERENCE!>foo<!>()
}
fun test_3(a: Any, b: Any, c: Any) {
with(a) wa@{
with(b) wb@{
with(c) wc@{
this@wb as A
this@wb.foo()
foo()
}
this.foo()
foo()
}
}
}
fun Any?.test_4() {
if (this !is A) {
this.<!UNRESOLVED_REFERENCE!>foo<!>()
<!UNRESOLVED_REFERENCE!>foo<!>()
this.<!UNRESOLVED_REFERENCE!>bar<!>()
<!UNRESOLVED_REFERENCE!>bar<!>()
} else if (this !is B) {
this.<!UNRESOLVED_REFERENCE!>bar<!>()
<!UNRESOLVED_REFERENCE!>bar<!>()
this.foo()
foo()
} else {
this.foo()
foo()
this.bar()
bar()
}
this.<!UNRESOLVED_REFERENCE!>foo<!>()
<!UNRESOLVED_REFERENCE!>foo<!>()
this.<!UNRESOLVED_REFERENCE!>bar<!>()
<!UNRESOLVED_REFERENCE!>bar<!>()
}
fun Any.test_5(): Int = when {
this is List<*> -> size
this is String -> length
else -> 0
}
fun Any.test_6() {
this as List<*>
size
this as String
length
}
@@ -0,0 +1,119 @@
FILE: implicitReceivers.kt
public final class A : R|kotlin/Any| {
public constructor(): R|A| {
super<R|kotlin/Any|>()
}
public final fun foo(): R|kotlin/Unit| {
}
}
public final class B : R|kotlin/Any| {
public constructor(): R|B| {
super<R|kotlin/Any|>()
}
public final fun bar(): R|kotlin/Unit| {
}
}
public final fun <T> R|T|.with(block: R|T.() -> kotlin/Unit|): R|kotlin/Unit| {
}
public final fun R|kotlin/Any?|.test_1(): R|kotlin/Unit| {
when () {
(this@R|/test_1| is R|A|) -> {
this@R|/test_1|.R|/A.foo|()
this@R|/test_1|.R|/A.foo|()
}
else -> {
this@R|/test_1|.<Unresolved name: foo>#()
<Unresolved name: foo>#()
}
}
this@R|/test_1|.<Unresolved name: foo>#()
<Unresolved name: foo>#()
}
public final fun R|kotlin/Any?|.test_2(): R|kotlin/Unit| {
when () {
(this@R|/test_2| !is R|A|) -> {
this@R|/test_2|.<Unresolved name: foo>#()
<Unresolved name: foo>#()
}
else -> {
this@R|/test_2|.R|/A.foo|()
this@R|/test_2|.R|/A.foo|()
}
}
this@R|/test_2|.<Unresolved name: foo>#()
<Unresolved name: foo>#()
}
public final fun test_3(a: R|kotlin/Any|, b: R|kotlin/Any|, c: R|kotlin/Any|): R|kotlin/Unit| {
R|kotlin/with|<R|kotlin/Any|, R|kotlin/Unit|>(R|<local>/a|, <L> = wa@fun R|kotlin/Any|.<anonymous>(): R|kotlin/Unit| <kind=EXACTLY_ONCE> {
^ R|kotlin/with|<R|kotlin/Any|, R|kotlin/Unit|>(R|<local>/b|, <L> = wb@fun R|kotlin/Any|.<anonymous>(): R|kotlin/Unit| <kind=EXACTLY_ONCE> {
R|kotlin/with|<R|kotlin/Any|, R|kotlin/Unit|>(R|<local>/c|, <L> = wc@fun R|kotlin/Any|.<anonymous>(): R|kotlin/Unit| <kind=EXACTLY_ONCE> {
(this@R|special/anonymous| as R|A|)
this@R|special/anonymous|.R|/A.foo|()
this@R|special/anonymous|.R|/A.foo|()
}
)
this@R|special/anonymous|.R|/A.foo|()
this@R|special/anonymous|.R|/A.foo|()
}
)
}
)
}
public final fun R|kotlin/Any?|.test_4(): R|kotlin/Unit| {
when () {
(this@R|/test_4| !is R|A|) -> {
this@R|/test_4|.<Unresolved name: foo>#()
<Unresolved name: foo>#()
this@R|/test_4|.<Unresolved name: bar>#()
<Unresolved name: bar>#()
}
else -> {
when () {
(this@R|/test_4| !is R|B|) -> {
this@R|/test_4|.<Unresolved name: bar>#()
<Unresolved name: bar>#()
this@R|/test_4|.R|/A.foo|()
this@R|/test_4|.R|/A.foo|()
}
else -> {
this@R|/test_4|.R|/A.foo|()
this@R|/test_4|.R|/A.foo|()
this@R|/test_4|.R|/B.bar|()
this@R|/test_4|.R|/B.bar|()
}
}
}
}
this@R|/test_4|.<Unresolved name: foo>#()
<Unresolved name: foo>#()
this@R|/test_4|.<Unresolved name: bar>#()
<Unresolved name: bar>#()
}
public final fun R|kotlin/Any|.test_5(): R|kotlin/Int| {
^test_5 when () {
(this@R|/test_5| is R|kotlin/collections/List<*>|) -> {
this@R|/test_5|.R|kotlin/collections/List.size|
}
(this@R|/test_5| is R|kotlin/String|) -> {
this@R|/test_5|.R|kotlin/String.length|
}
else -> {
Int(0)
}
}
}
public final fun R|kotlin/Any|.test_6(): R|kotlin/Unit| {
(this@R|/test_6| as R|kotlin/collections/List<*>|)
this@R|/test_6|.R|kotlin/collections/List.size|
(this@R|/test_6| as R|kotlin/String|)
this@R|/test_6|.R|kotlin/String.length|
}
@@ -0,0 +1,14 @@
fun takeString(s: String) {}
class Wrapper(val s: String?) {
fun withThis() {
if (s != null) {
takeString(this.s) // Should be OK
}
if (this.s != null) {
takeString(s) // Should be OK
}
}
}
fun takeString(s: String) {}
@@ -0,0 +1,29 @@
FILE: mixingImplicitAndExplicitReceivers.kt
public final fun takeString(s: R|kotlin/String|): R|kotlin/Unit| {
}
public final class Wrapper : R|kotlin/Any| {
public constructor(s: R|kotlin/String?|): R|Wrapper| {
super<R|kotlin/Any|>()
}
public final val s: R|kotlin/String?| = R|<local>/s|
public get(): R|kotlin/String?|
public final fun withThis(): R|kotlin/Unit| {
when () {
!=(this@R|/Wrapper|.R|/Wrapper.s|, Null(null)) -> {
R|/takeString|(this@R|/Wrapper|.R|/Wrapper.s|)
}
}
when () {
!=(this@R|/Wrapper|.R|/Wrapper.s|, Null(null)) -> {
R|/takeString|(this@R|/Wrapper|.R|/Wrapper.s|)
}
}
}
}
public final fun takeString(s: R|kotlin/String|): R|kotlin/Unit| {
}
@@ -0,0 +1,100 @@
digraph thisOfExtensionProperty_kt {
graph [nodesep=3]
node [shape=box penwidth=2]
edge [penwidth=2]
subgraph cluster_0 {
color=red
0 [label="Enter function getter" style="filled" fillcolor=red];
1 [label="Exit function getter" style="filled" fillcolor=red];
}
0 -> {1};
subgraph cluster_1 {
color=red
2 [label="Enter property" style="filled" fillcolor=red];
3 [label="Exit property" style="filled" fillcolor=red];
}
2 -> {3};
subgraph cluster_2 {
color=red
4 [label="Enter function getter" style="filled" fillcolor=red];
subgraph cluster_3 {
color=blue
5 [label="Enter &&"];
6 [label="Access variable this@R|/check_1|"];
7 [label="Type operator: (this@R|/check_1| is R|B|)"];
8 [label="Exit left part of &&"];
9 [label="Enter right part of &&"];
10 [label="Access variable R|/B.b|"];
11 [label="Exit &&"];
}
12 [label="Jump: ^ (this@R|/check_1| is R|B|) && this@R|/check_1|.R|/B.b|"];
13 [label="Stub" style="filled" fillcolor=gray];
14 [label="Exit function getter" style="filled" fillcolor=red];
}
4 -> {5};
5 -> {6};
6 -> {7};
7 -> {8};
8 -> {11 9};
9 -> {10};
10 -> {11};
11 -> {12};
12 -> {14};
12 -> {13} [style=dotted];
13 -> {14} [style=dotted];
subgraph cluster_4 {
color=red
15 [label="Enter property" style="filled" fillcolor=red];
16 [label="Exit property" style="filled" fillcolor=red];
}
15 -> {16};
subgraph cluster_5 {
color=red
17 [label="Enter function getter" style="filled" fillcolor=red];
subgraph cluster_6 {
color=blue
18 [label="Enter &&"];
19 [label="Access variable this@R|/check_2|"];
20 [label="Type operator: (this@R|/check_2| is R|B|)"];
21 [label="Exit left part of &&"];
22 [label="Enter right part of &&"];
23 [label="Access variable this@R|/check_2|"];
24 [label="Access variable R|/B.b|"];
25 [label="Exit &&"];
}
26 [label="Jump: ^ (this@R|/check_2| is R|B|) && this@R|/check_2|.R|/B.b|"];
27 [label="Stub" style="filled" fillcolor=gray];
28 [label="Exit function getter" style="filled" fillcolor=red];
}
17 -> {18};
18 -> {19};
19 -> {20};
20 -> {21};
21 -> {25 22};
22 -> {23};
23 -> {24};
24 -> {25};
25 -> {26};
26 -> {28};
26 -> {27} [style=dotted];
27 -> {28} [style=dotted];
subgraph cluster_7 {
color=red
29 [label="Enter property" style="filled" fillcolor=red];
30 [label="Exit property" style="filled" fillcolor=red];
}
29 -> {30};
}
@@ -0,0 +1,12 @@
// !DUMP_CFG
interface A
interface B {
val b: Boolean
}
val A.check_1: Boolean
get() = this is B && b
val A.check_2: Boolean
get() = this is B && this.b
@@ -0,0 +1,16 @@
FILE: thisOfExtensionProperty.kt
public abstract interface A : R|kotlin/Any| {
}
public abstract interface B : R|kotlin/Any| {
public abstract val b: R|kotlin/Boolean|
public get(): R|kotlin/Boolean|
}
public final val R|A|.check_1: R|kotlin/Boolean|
public get(): R|kotlin/Boolean| {
^ (this@R|/check_1| is R|B|) && this@R|/check_1|.R|/B.b|
}
public final val R|A|.check_2: R|kotlin/Boolean|
public get(): R|kotlin/Boolean| {
^ (this@R|/check_2| is R|B|) && this@R|/check_2|.R|/B.b|
}
@@ -0,0 +1,465 @@
digraph assignSafeCall_kt {
graph [nodesep=3]
node [shape=box penwidth=2]
edge [penwidth=2]
subgraph cluster_0 {
color=red
0 [label="Enter function <init>" style="filled" fillcolor=red];
1 [label="Delegated constructor call: super<R|kotlin/Any|>()"];
2 [label="Exit function <init>" style="filled" fillcolor=red];
}
0 -> {1};
1 -> {2};
subgraph cluster_1 {
color=red
3 [label="Enter function foo" style="filled" fillcolor=red];
4 [label="Const: Int(1)"];
5 [label="Jump: ^foo Int(1)"];
6 [label="Stub" style="filled" fillcolor=gray];
7 [label="Exit function foo" style="filled" fillcolor=red];
}
3 -> {4};
4 -> {5};
5 -> {7};
5 -> {6} [style=dotted];
6 -> {7} [style=dotted];
subgraph cluster_2 {
color=red
8 [label="Enter function getter" style="filled" fillcolor=red];
9 [label="Exit function getter" style="filled" fillcolor=red];
}
8 -> {9};
subgraph cluster_3 {
color=red
10 [label="Enter property" style="filled" fillcolor=red];
11 [label="Const: Int(1)"];
12 [label="Exit property" style="filled" fillcolor=red];
}
10 -> {11};
11 -> {12};
subgraph cluster_4 {
color=red
13 [label="Enter function bar" style="filled" fillcolor=red];
14 [label="Exit function bar" style="filled" fillcolor=red];
}
13 -> {14};
subgraph cluster_5 {
color=red
15 [label="Enter function test_1" style="filled" fillcolor=red];
16 [label="Access variable R|<local>/a|"];
17 [label="Enter safe call"];
18 [label="Access variable R|/A.x|"];
19 [label="Exit safe call"];
20 [label="Variable declaration: lval x: R|kotlin/Int?|"];
subgraph cluster_6 {
color=blue
21 [label="Enter when"];
subgraph cluster_7 {
color=blue
22 [label="Enter when branch condition "];
23 [label="Access variable R|<local>/x|"];
24 [label="Const: Null(null)"];
25 [label="Operator !="];
26 [label="Exit when branch condition"];
}
27 [label="Synthetic else branch"];
28 [label="Enter when branch result"];
subgraph cluster_8 {
color=blue
29 [label="Enter block"];
30 [label="Access variable R|<local>/a|"];
31 [label="Function call: R|<local>/a|.R|/A.bar|()"];
32 [label="Exit block"];
}
33 [label="Exit when branch result"];
34 [label="Exit when"];
}
35 [label="Exit function test_1" style="filled" fillcolor=red];
}
15 -> {16};
16 -> {17 19};
17 -> {18};
18 -> {19};
19 -> {20};
20 -> {21};
21 -> {22};
22 -> {23};
23 -> {24};
24 -> {25};
25 -> {26};
26 -> {28 27};
27 -> {34};
28 -> {29};
29 -> {30};
30 -> {31};
31 -> {32};
32 -> {33};
33 -> {34};
34 -> {35};
subgraph cluster_9 {
color=red
36 [label="Enter function test_2" style="filled" fillcolor=red];
37 [label="Access variable R|<local>/a|"];
38 [label="Enter safe call"];
39 [label="Function call: R|<local>/a|?.R|/A.foo|()"];
40 [label="Exit safe call"];
41 [label="Variable declaration: lval x: R|kotlin/Int?|"];
subgraph cluster_10 {
color=blue
42 [label="Enter when"];
subgraph cluster_11 {
color=blue
43 [label="Enter when branch condition "];
44 [label="Access variable R|<local>/x|"];
45 [label="Const: Null(null)"];
46 [label="Operator !="];
47 [label="Exit when branch condition"];
}
48 [label="Synthetic else branch"];
49 [label="Enter when branch result"];
subgraph cluster_12 {
color=blue
50 [label="Enter block"];
51 [label="Access variable R|<local>/a|"];
52 [label="Function call: R|<local>/a|.R|/A.bar|()"];
53 [label="Exit block"];
}
54 [label="Exit when branch result"];
55 [label="Exit when"];
}
56 [label="Exit function test_2" style="filled" fillcolor=red];
}
36 -> {37};
37 -> {38 40};
38 -> {39};
39 -> {40};
40 -> {41};
41 -> {42};
42 -> {43};
43 -> {44};
44 -> {45};
45 -> {46};
46 -> {47};
47 -> {49 48};
48 -> {55};
49 -> {50};
50 -> {51};
51 -> {52};
52 -> {53};
53 -> {54};
54 -> {55};
55 -> {56};
subgraph cluster_13 {
color=red
57 [label="Enter function test_3" style="filled" fillcolor=red];
subgraph cluster_14 {
color=blue
58 [label="Enter when"];
59 [label="Access variable R|<local>/x|"];
60 [label="Type operator: (R|<local>/x| as? R|A|)"];
61 [label="Variable declaration: lval <elvis>: R|A?|"];
subgraph cluster_15 {
color=blue
62 [label="Enter when branch condition "];
63 [label="Const: Null(null)"];
64 [label="Operator =="];
65 [label="Exit when branch condition"];
}
subgraph cluster_16 {
color=blue
66 [label="Enter when branch condition else"];
67 [label="Exit when branch condition"];
}
68 [label="Enter when branch result"];
subgraph cluster_17 {
color=blue
69 [label="Enter block"];
70 [label="Access variable R|<local>/<elvis>|"];
71 [label="Exit block"];
}
72 [label="Exit when branch result"];
73 [label="Enter when branch result"];
subgraph cluster_18 {
color=blue
74 [label="Enter block"];
75 [label="Jump: ^test_3 Unit"];
76 [label="Stub" style="filled" fillcolor=gray];
77 [label="Exit block" style="filled" fillcolor=gray];
}
78 [label="Exit when branch result" style="filled" fillcolor=gray];
79 [label="Exit when"];
}
80 [label="Variable declaration: lval a: R|A|"];
81 [label="Access variable R|<local>/a|"];
82 [label="Function call: R|<local>/a|.R|/A.foo|()"];
83 [label="Access variable R|<local>/x|"];
84 [label="Function call: R|<local>/x|.R|/A.foo|()"];
85 [label="Exit function test_3" style="filled" fillcolor=red];
}
57 -> {58};
58 -> {59};
59 -> {60};
60 -> {61};
61 -> {62};
62 -> {63};
63 -> {64};
64 -> {65};
65 -> {73 66};
66 -> {67};
67 -> {68};
68 -> {69};
69 -> {70};
70 -> {71};
71 -> {72};
72 -> {79};
73 -> {74};
74 -> {75};
75 -> {85};
75 -> {76} [style=dotted];
76 -> {77} [style=dotted];
77 -> {78} [style=dotted];
78 -> {79} [style=dotted];
79 -> {80};
80 -> {81};
81 -> {82};
82 -> {83};
83 -> {84};
84 -> {85};
subgraph cluster_19 {
color=red
86 [label="Enter function foo" style="filled" fillcolor=red];
87 [label="Exit function foo" style="filled" fillcolor=red];
}
86 -> {87};
subgraph cluster_20 {
color=red
88 [label="Enter function getter" style="filled" fillcolor=red];
89 [label="Exit function getter" style="filled" fillcolor=red];
}
88 -> {89};
subgraph cluster_21 {
color=red
90 [label="Enter property" style="filled" fillcolor=red];
91 [label="Exit property" style="filled" fillcolor=red];
}
90 -> {91};
subgraph cluster_22 {
color=red
92 [label="Enter function bar" style="filled" fillcolor=red];
93 [label="Exit function bar" style="filled" fillcolor=red];
}
92 -> {93};
subgraph cluster_23 {
color=red
94 [label="Enter function test_1" style="filled" fillcolor=red];
95 [label="Access variable R|<local>/a|"];
96 [label="Enter safe call"];
97 [label="Access variable R|/B.x|"];
98 [label="Exit safe call"];
99 [label="Variable declaration: lval x: R|kotlin/Int?|"];
subgraph cluster_24 {
color=blue
100 [label="Enter when"];
subgraph cluster_25 {
color=blue
101 [label="Enter when branch condition "];
102 [label="Access variable R|<local>/x|"];
103 [label="Const: Null(null)"];
104 [label="Operator !="];
105 [label="Exit when branch condition"];
}
106 [label="Synthetic else branch"];
107 [label="Enter when branch result"];
subgraph cluster_26 {
color=blue
108 [label="Enter block"];
109 [label="Access variable R|<local>/a|"];
110 [label="Function call: R|<local>/a|.R|/B.bar|()"];
111 [label="Exit block"];
}
112 [label="Exit when branch result"];
113 [label="Exit when"];
}
114 [label="Exit function test_1" style="filled" fillcolor=red];
}
94 -> {95};
95 -> {96 98};
96 -> {97};
97 -> {98};
98 -> {99};
99 -> {100};
100 -> {101};
101 -> {102};
102 -> {103};
103 -> {104};
104 -> {105};
105 -> {107 106};
106 -> {113};
107 -> {108};
108 -> {109};
109 -> {110};
110 -> {111};
111 -> {112};
112 -> {113};
113 -> {114};
subgraph cluster_27 {
color=red
115 [label="Enter function test_2" style="filled" fillcolor=red];
116 [label="Access variable R|<local>/a|"];
117 [label="Enter safe call"];
118 [label="Function call: R|<local>/a|?.R|/B.foo|()"];
119 [label="Exit safe call"];
120 [label="Variable declaration: lval x: R|kotlin/Int?|"];
subgraph cluster_28 {
color=blue
121 [label="Enter when"];
subgraph cluster_29 {
color=blue
122 [label="Enter when branch condition "];
123 [label="Access variable R|<local>/x|"];
124 [label="Const: Null(null)"];
125 [label="Operator !="];
126 [label="Exit when branch condition"];
}
127 [label="Synthetic else branch"];
128 [label="Enter when branch result"];
subgraph cluster_30 {
color=blue
129 [label="Enter block"];
130 [label="Access variable R|<local>/a|"];
131 [label="Function call: R|<local>/a|.R|/B.bar|()"];
132 [label="Exit block"];
}
133 [label="Exit when branch result"];
134 [label="Exit when"];
}
135 [label="Exit function test_2" style="filled" fillcolor=red];
}
115 -> {116};
116 -> {117 119};
117 -> {118};
118 -> {119};
119 -> {120};
120 -> {121};
121 -> {122};
122 -> {123};
123 -> {124};
124 -> {125};
125 -> {126};
126 -> {128 127};
127 -> {134};
128 -> {129};
129 -> {130};
130 -> {131};
131 -> {132};
132 -> {133};
133 -> {134};
134 -> {135};
subgraph cluster_31 {
color=red
136 [label="Enter function test_3" style="filled" fillcolor=red];
subgraph cluster_32 {
color=blue
137 [label="Enter when"];
138 [label="Access variable R|<local>/x|"];
139 [label="Type operator: (R|<local>/x| as? R|B|)"];
140 [label="Variable declaration: lval <elvis>: R|B?|"];
subgraph cluster_33 {
color=blue
141 [label="Enter when branch condition "];
142 [label="Const: Null(null)"];
143 [label="Operator =="];
144 [label="Exit when branch condition"];
}
subgraph cluster_34 {
color=blue
145 [label="Enter when branch condition else"];
146 [label="Exit when branch condition"];
}
147 [label="Enter when branch result"];
subgraph cluster_35 {
color=blue
148 [label="Enter block"];
149 [label="Access variable R|<local>/<elvis>|"];
150 [label="Exit block"];
}
151 [label="Exit when branch result"];
152 [label="Enter when branch result"];
subgraph cluster_36 {
color=blue
153 [label="Enter block"];
154 [label="Jump: ^test_3 Unit"];
155 [label="Stub" style="filled" fillcolor=gray];
156 [label="Exit block" style="filled" fillcolor=gray];
}
157 [label="Exit when branch result" style="filled" fillcolor=gray];
158 [label="Exit when"];
}
159 [label="Variable declaration: lval a: R|B|"];
160 [label="Access variable R|<local>/a|"];
161 [label="Function call: R|<local>/a|.R|/B.foo|()"];
162 [label="Access variable R|<local>/x|"];
163 [label="Function call: R|<local>/x|.R|/B.foo|()"];
164 [label="Exit function test_3" style="filled" fillcolor=red];
}
136 -> {137};
137 -> {138};
138 -> {139};
139 -> {140};
140 -> {141};
141 -> {142};
142 -> {143};
143 -> {144};
144 -> {152 145};
145 -> {146};
146 -> {147};
147 -> {148};
148 -> {149};
149 -> {150};
150 -> {151};
151 -> {158};
152 -> {153};
153 -> {154};
154 -> {164};
154 -> {155} [style=dotted];
155 -> {156} [style=dotted];
156 -> {157} [style=dotted];
157 -> {158} [style=dotted];
158 -> {159};
159 -> {160};
160 -> {161};
161 -> {162};
162 -> {163};
163 -> {164};
}
@@ -0,0 +1,60 @@
// !DUMP_CFG
// ----------------- Stable -----------------
class A {
fun foo(): Int = 1
val x: Int = 1
fun bar() {}
}
fun test_1(a: A?) {
val x = a?.x
if (x != null) {
a.bar() // Should be OK
}
}
fun test_2(a: A?) {
val x = a?.foo()
if (x != null) {
a.bar() // Should be OK
}
}
fun test_3(x: Any?) {
val a = x as? A ?: return
a.foo() // Should be OK
x.foo() // Should be OK
}
// ----------------- Unstable -----------------
interface B {
fun foo(): Int
val x: Int
fun bar()
}
fun test_1(a: B?) {
val x = a?.x
if (x != null) {
a.bar() // Should be OK
}
}
fun test_2(a: B?) {
val x = a?.foo()
if (x != null) {
a.bar() // Should be OK
}
}
fun test_3(x: Any?) {
val a = x as? B ?: return
a.foo() // Should be OK
x.foo() // Should be OK
}
@@ -0,0 +1,88 @@
FILE: assignSafeCall.kt
public final class A : R|kotlin/Any| {
public constructor(): R|A| {
super<R|kotlin/Any|>()
}
public final fun foo(): R|kotlin/Int| {
^foo Int(1)
}
public final val x: R|kotlin/Int| = Int(1)
public get(): R|kotlin/Int|
public final fun bar(): R|kotlin/Unit| {
}
}
public final fun test_1(a: R|A?|): R|kotlin/Unit| {
lval x: R|kotlin/Int?| = R|<local>/a|?.R|/A.x|
when () {
!=(R|<local>/x|, Null(null)) -> {
R|<local>/a|.R|/A.bar|()
}
}
}
public final fun test_2(a: R|A?|): R|kotlin/Unit| {
lval x: R|kotlin/Int?| = R|<local>/a|?.R|/A.foo|()
when () {
!=(R|<local>/x|, Null(null)) -> {
R|<local>/a|.R|/A.bar|()
}
}
}
public final fun test_3(x: R|kotlin/Any?|): R|kotlin/Unit| {
lval a: R|A| = when (lval <elvis>: R|A?| = (R|<local>/x| as? R|A|)) {
==($subj$, Null(null)) -> {
^test_3 Unit
}
else -> {
R|<local>/<elvis>|
}
}
R|<local>/a|.R|/A.foo|()
R|<local>/x|.R|/A.foo|()
}
public abstract interface B : R|kotlin/Any| {
public abstract fun foo(): R|kotlin/Int|
public abstract val x: R|kotlin/Int|
public get(): R|kotlin/Int|
public abstract fun bar(): R|kotlin/Unit|
}
public final fun test_1(a: R|B?|): R|kotlin/Unit| {
lval x: R|kotlin/Int?| = R|<local>/a|?.R|/B.x|
when () {
!=(R|<local>/x|, Null(null)) -> {
R|<local>/a|.R|/B.bar|()
}
}
}
public final fun test_2(a: R|B?|): R|kotlin/Unit| {
lval x: R|kotlin/Int?| = R|<local>/a|?.R|/B.foo|()
when () {
!=(R|<local>/x|, Null(null)) -> {
R|<local>/a|.R|/B.bar|()
}
}
}
public final fun test_3(x: R|kotlin/Any?|): R|kotlin/Unit| {
lval a: R|B| = when (lval <elvis>: R|B?| = (R|<local>/x| as? R|B|)) {
==($subj$, Null(null)) -> {
^test_3 Unit
}
else -> {
R|<local>/<elvis>|
}
}
R|<local>/a|.R|/B.foo|()
R|<local>/x|.R|/B.foo|()
}
@@ -0,0 +1,305 @@
digraph safeCallAndEqualityToBool_kt {
graph [nodesep=3]
node [shape=box penwidth=2]
edge [penwidth=2]
subgraph cluster_0 {
color=red
0 [label="Enter function check" style="filled" fillcolor=red];
1 [label="Const: Boolean(true)"];
2 [label="Jump: ^check Boolean(true)"];
3 [label="Stub" style="filled" fillcolor=gray];
4 [label="Exit function check" style="filled" fillcolor=red];
}
0 -> {1};
1 -> {2};
2 -> {4};
2 -> {3} [style=dotted];
3 -> {4} [style=dotted];
subgraph cluster_1 {
color=red
5 [label="Enter function test_1" style="filled" fillcolor=red];
subgraph cluster_2 {
color=blue
6 [label="Enter when"];
subgraph cluster_3 {
color=blue
7 [label="Enter when branch condition "];
8 [label="Access variable R|<local>/s|"];
9 [label="Enter safe call"];
10 [label="Function call: R|<local>/s|?.R|/check|()"];
11 [label="Exit safe call"];
12 [label="Const: Boolean(true)"];
13 [label="Operator =="];
14 [label="Exit when branch condition"];
}
subgraph cluster_4 {
color=blue
15 [label="Enter when branch condition else"];
16 [label="Exit when branch condition"];
}
17 [label="Enter when branch result"];
subgraph cluster_5 {
color=blue
18 [label="Enter block"];
19 [label="Access variable R|<local>/s|"];
20 [label="Access variable <Inapplicable(WRONG_RECEIVER): [kotlin/String.length]>#"];
21 [label="Exit block"];
}
22 [label="Exit when branch result"];
23 [label="Enter when branch result"];
subgraph cluster_6 {
color=blue
24 [label="Enter block"];
25 [label="Access variable R|<local>/s|"];
26 [label="Access variable R|kotlin/String.length|"];
27 [label="Exit block"];
}
28 [label="Exit when branch result"];
29 [label="Exit when"];
}
30 [label="Exit function test_1" style="filled" fillcolor=red];
}
5 -> {6};
6 -> {7};
7 -> {8};
8 -> {9 11};
9 -> {10};
10 -> {11};
11 -> {12};
12 -> {13};
13 -> {14};
14 -> {23 15};
15 -> {16};
16 -> {17};
17 -> {18};
18 -> {19};
19 -> {20};
20 -> {21};
21 -> {22};
22 -> {29};
23 -> {24};
24 -> {25};
25 -> {26};
26 -> {27};
27 -> {28};
28 -> {29};
29 -> {30};
subgraph cluster_7 {
color=red
31 [label="Enter function test_2" style="filled" fillcolor=red];
subgraph cluster_8 {
color=blue
32 [label="Enter when"];
subgraph cluster_9 {
color=blue
33 [label="Enter when branch condition "];
34 [label="Access variable R|<local>/s|"];
35 [label="Enter safe call"];
36 [label="Function call: R|<local>/s|?.R|/check|()"];
37 [label="Exit safe call"];
38 [label="Const: Boolean(false)"];
39 [label="Operator =="];
40 [label="Exit when branch condition"];
}
subgraph cluster_10 {
color=blue
41 [label="Enter when branch condition else"];
42 [label="Exit when branch condition"];
}
43 [label="Enter when branch result"];
subgraph cluster_11 {
color=blue
44 [label="Enter block"];
45 [label="Access variable R|<local>/s|"];
46 [label="Access variable <Inapplicable(WRONG_RECEIVER): [kotlin/String.length]>#"];
47 [label="Exit block"];
}
48 [label="Exit when branch result"];
49 [label="Enter when branch result"];
subgraph cluster_12 {
color=blue
50 [label="Enter block"];
51 [label="Access variable R|<local>/s|"];
52 [label="Access variable R|kotlin/String.length|"];
53 [label="Exit block"];
}
54 [label="Exit when branch result"];
55 [label="Exit when"];
}
56 [label="Exit function test_2" style="filled" fillcolor=red];
}
31 -> {32};
32 -> {33};
33 -> {34};
34 -> {35 37};
35 -> {36};
36 -> {37};
37 -> {38};
38 -> {39};
39 -> {40};
40 -> {49 41};
41 -> {42};
42 -> {43};
43 -> {44};
44 -> {45};
45 -> {46};
46 -> {47};
47 -> {48};
48 -> {55};
49 -> {50};
50 -> {51};
51 -> {52};
52 -> {53};
53 -> {54};
54 -> {55};
55 -> {56};
subgraph cluster_13 {
color=red
57 [label="Enter function test_3" style="filled" fillcolor=red];
subgraph cluster_14 {
color=blue
58 [label="Enter when"];
subgraph cluster_15 {
color=blue
59 [label="Enter when branch condition "];
60 [label="Access variable R|<local>/s|"];
61 [label="Enter safe call"];
62 [label="Function call: R|<local>/s|?.R|/check|()"];
63 [label="Exit safe call"];
64 [label="Const: Boolean(true)"];
65 [label="Operator !="];
66 [label="Exit when branch condition"];
}
subgraph cluster_16 {
color=blue
67 [label="Enter when branch condition else"];
68 [label="Exit when branch condition"];
}
69 [label="Enter when branch result"];
subgraph cluster_17 {
color=blue
70 [label="Enter block"];
71 [label="Access variable R|<local>/s|"];
72 [label="Access variable R|kotlin/String.length|"];
73 [label="Exit block"];
}
74 [label="Exit when branch result"];
75 [label="Enter when branch result"];
subgraph cluster_18 {
color=blue
76 [label="Enter block"];
77 [label="Access variable R|<local>/s|"];
78 [label="Access variable <Inapplicable(WRONG_RECEIVER): [kotlin/String.length]>#"];
79 [label="Exit block"];
}
80 [label="Exit when branch result"];
81 [label="Exit when"];
}
82 [label="Exit function test_3" style="filled" fillcolor=red];
}
57 -> {58};
58 -> {59};
59 -> {60};
60 -> {61 63};
61 -> {62};
62 -> {63};
63 -> {64};
64 -> {65};
65 -> {66};
66 -> {75 67};
67 -> {68};
68 -> {69};
69 -> {70};
70 -> {71};
71 -> {72};
72 -> {73};
73 -> {74};
74 -> {81};
75 -> {76};
76 -> {77};
77 -> {78};
78 -> {79};
79 -> {80};
80 -> {81};
81 -> {82};
subgraph cluster_19 {
color=red
83 [label="Enter function test_4" style="filled" fillcolor=red];
subgraph cluster_20 {
color=blue
84 [label="Enter when"];
subgraph cluster_21 {
color=blue
85 [label="Enter when branch condition "];
86 [label="Access variable R|<local>/s|"];
87 [label="Enter safe call"];
88 [label="Function call: R|<local>/s|?.R|/check|()"];
89 [label="Exit safe call"];
90 [label="Const: Boolean(false)"];
91 [label="Operator !="];
92 [label="Exit when branch condition"];
}
subgraph cluster_22 {
color=blue
93 [label="Enter when branch condition else"];
94 [label="Exit when branch condition"];
}
95 [label="Enter when branch result"];
subgraph cluster_23 {
color=blue
96 [label="Enter block"];
97 [label="Access variable R|<local>/s|"];
98 [label="Access variable R|kotlin/String.length|"];
99 [label="Exit block"];
}
100 [label="Exit when branch result"];
101 [label="Enter when branch result"];
subgraph cluster_24 {
color=blue
102 [label="Enter block"];
103 [label="Access variable R|<local>/s|"];
104 [label="Access variable <Inapplicable(WRONG_RECEIVER): [kotlin/String.length]>#"];
105 [label="Exit block"];
}
106 [label="Exit when branch result"];
107 [label="Exit when"];
}
108 [label="Exit function test_4" style="filled" fillcolor=red];
}
83 -> {84};
84 -> {85};
85 -> {86};
86 -> {87 89};
87 -> {88};
88 -> {89};
89 -> {90};
90 -> {91};
91 -> {92};
92 -> {101 93};
93 -> {94};
94 -> {95};
95 -> {96};
96 -> {97};
97 -> {98};
98 -> {99};
99 -> {100};
100 -> {107};
101 -> {102};
102 -> {103};
103 -> {104};
104 -> {105};
105 -> {106};
106 -> {107};
107 -> {108};
}
@@ -0,0 +1,34 @@
// !DUMP_CFG
fun String.check(): Boolean = true
fun test_1(s: String?) {
if (s?.check() == true) {
s.length // Should be OK
} else {
s.<!INAPPLICABLE_CANDIDATE!>length<!> // Should be bad
}
}
fun test_2(s: String?) {
if (s?.check() == false) {
s.length // Should be OK
} else {
s.<!INAPPLICABLE_CANDIDATE!>length<!> // Should be bad
}
}
fun test_3(s: String?) {
if (s?.check() != true) {
s.<!INAPPLICABLE_CANDIDATE!>length<!> // Should be bad
} else {
s.length // Should be OK
}
}
fun test_4(s: String?) {
if (s?.check() != false) {
s.<!INAPPLICABLE_CANDIDATE!>length<!> // Should be bad
} else {
s.length // Should be OK
}
}
@@ -0,0 +1,48 @@
FILE: safeCallAndEqualityToBool.kt
public final fun R|kotlin/String|.check(): R|kotlin/Boolean| {
^check Boolean(true)
}
public final fun test_1(s: R|kotlin/String?|): R|kotlin/Unit| {
when () {
==(R|<local>/s|?.R|/check|(), Boolean(true)) -> {
R|<local>/s|.R|kotlin/String.length|
}
else -> {
R|<local>/s|.<Inapplicable(WRONG_RECEIVER): [kotlin/String.length]>#
}
}
}
public final fun test_2(s: R|kotlin/String?|): R|kotlin/Unit| {
when () {
==(R|<local>/s|?.R|/check|(), Boolean(false)) -> {
R|<local>/s|.R|kotlin/String.length|
}
else -> {
R|<local>/s|.<Inapplicable(WRONG_RECEIVER): [kotlin/String.length]>#
}
}
}
public final fun test_3(s: R|kotlin/String?|): R|kotlin/Unit| {
when () {
!=(R|<local>/s|?.R|/check|(), Boolean(true)) -> {
R|<local>/s|.<Inapplicable(WRONG_RECEIVER): [kotlin/String.length]>#
}
else -> {
R|<local>/s|.R|kotlin/String.length|
}
}
}
public final fun test_4(s: R|kotlin/String?|): R|kotlin/Unit| {
when () {
!=(R|<local>/s|?.R|/check|(), Boolean(false)) -> {
R|<local>/s|.<Inapplicable(WRONG_RECEIVER): [kotlin/String.length]>#
}
else -> {
R|<local>/s|.R|kotlin/String.length|
}
}
}
@@ -0,0 +1,241 @@
digraph safeCalls_kt {
graph [nodesep=3]
node [shape=box penwidth=2]
edge [penwidth=2]
subgraph cluster_0 {
color=red
0 [label="Enter function foo" style="filled" fillcolor=red];
1 [label="Const: String()"];
2 [label="Jump: ^foo String()"];
3 [label="Stub" style="filled" fillcolor=gray];
4 [label="Exit function foo" style="filled" fillcolor=red];
}
0 -> {1};
1 -> {2};
2 -> {4};
2 -> {3} [style=dotted];
3 -> {4} [style=dotted];
subgraph cluster_1 {
color=red
5 [label="Enter function let" style="filled" fillcolor=red];
6 [label="Exit function let" style="filled" fillcolor=red];
}
5 -> {6};
subgraph cluster_2 {
color=red
7 [label="Enter function test" style="filled" fillcolor=red];
8 [label="Access variable R|<local>/x|"];
9 [label="Enter safe call"];
10 [label="Access variable R|<local>/x|"];
11 [label="Access variable R|kotlin/String.length|"];
12 [label="Const: Int(1)"];
13 [label="Operator =="];
14 [label="Function call: R|<local>/x|?.R|/foo|(...)"];
15 [label="Exit safe call"];
16 [label="Access variable R|<local>/x|"];
17 [label="Access variable <Inapplicable(WRONG_RECEIVER): [kotlin/String.length]>#"];
18 [label="Exit function test" style="filled" fillcolor=red];
}
7 -> {8};
8 -> {9 15};
9 -> {10};
10 -> {11};
11 -> {12};
12 -> {13};
13 -> {14};
14 -> {15};
15 -> {16};
16 -> {17};
17 -> {18};
subgraph cluster_3 {
color=red
19 [label="Enter function bar" style="filled" fillcolor=red];
20 [label="Exit function bar" style="filled" fillcolor=red];
}
19 -> {20};
subgraph cluster_4 {
color=red
21 [label="Enter function bool" style="filled" fillcolor=red];
22 [label="Exit function bool" style="filled" fillcolor=red];
}
21 -> {22};
subgraph cluster_5 {
color=red
23 [label="Enter function id" style="filled" fillcolor=red];
24 [label="Exit function id" style="filled" fillcolor=red];
}
23 -> {24};
subgraph cluster_6 {
color=red
25 [label="Enter function test_2" style="filled" fillcolor=red];
26 [label="Access variable R|<local>/x|"];
27 [label="Type operator: (R|<local>/x| as? R|A|)"];
28 [label="Enter safe call"];
29 [label="Access variable R|<local>/x|"];
30 [label="Function call: (R|<local>/x| as? R|A|)?.R|/A.bar|(...)"];
31 [label="Exit safe call"];
32 [label="Exit function test_2" style="filled" fillcolor=red];
}
25 -> {26};
26 -> {27};
27 -> {28 31};
28 -> {29};
29 -> {30};
30 -> {31};
31 -> {32};
subgraph cluster_7 {
color=red
33 [label="Enter function test_3" style="filled" fillcolor=red];
34 [label="Access variable R|<local>/x|"];
35 [label="Type operator: (R|<local>/x| as? R|A|)"];
36 [label="Enter safe call"];
37 [label="Access variable R|<local>/x|"];
38 [label="Function call: (R|<local>/x| as? R|A|)?.R|/A.bar|(...)"];
39 [label="Exit safe call"];
40 [label="Enter safe call"];
41 [label="Access variable R|<local>/x|"];
42 [label="Function call: R|<local>/x|.R|/A.bool|()"];
43 [label="Function call: (R|<local>/x| as? R|A|)?.R|/A.bar|(...)?.R|/foo|(...)"];
44 [label="Exit safe call"];
45 [label="Enter safe call"];
46 [label="Postponed enter to lambda"];
47 [label="Postponed exit from lambda"];
48 [label="Function call: (R|<local>/x| as? R|A|)?.R|/A.bar|(...)?.R|/foo|(...)?.R|/let|(...)"];
49 [label="Exit safe call"];
50 [label="Access variable R|<local>/x|"];
51 [label="Function call: R|<local>/x|.<Unresolved name: bool>#()"];
52 [label="Exit function test_3" style="filled" fillcolor=red];
}
33 -> {34};
34 -> {35};
35 -> {36 39};
36 -> {37};
37 -> {38};
38 -> {39};
39 -> {40 44};
40 -> {41};
41 -> {42};
42 -> {43};
43 -> {44};
44 -> {45 49};
45 -> {46};
46 -> {47 47} [color=green];
47 -> {48};
48 -> {49};
49 -> {50};
50 -> {51};
51 -> {52};
subgraph cluster_8 {
color=red
53 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
54 [label="Access variable R|<local>/x|"];
55 [label="Function call: R|<local>/x|.R|/A.bool|()"];
56 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
53 -> {54};
54 -> {55};
55 -> {56};
subgraph cluster_9 {
color=red
57 [label="Enter function test_4" style="filled" fillcolor=red];
58 [label="Access variable R|<local>/x|"];
59 [label="Enter safe call"];
60 [label="Function call: R|<local>/x|?.R|/A.id|()"];
61 [label="Exit safe call"];
62 [label="Enter safe call"];
63 [label="Function call: R|<local>/x|?.R|/A.id|()?.R|/A.bool|()"];
64 [label="Exit safe call"];
65 [label="Access variable R|<local>/x|"];
66 [label="Function call: R|<local>/x|.<Inapplicable(WRONG_RECEIVER): [/A.id]>#()"];
67 [label="Exit function test_4" style="filled" fillcolor=red];
}
57 -> {58};
58 -> {59 61};
59 -> {60};
60 -> {61};
61 -> {62 64};
62 -> {63};
63 -> {64};
64 -> {65};
65 -> {66};
66 -> {67};
subgraph cluster_10 {
color=red
68 [label="Enter function boo" style="filled" fillcolor=red];
69 [label="Exit function boo" style="filled" fillcolor=red];
}
68 -> {69};
subgraph cluster_11 {
color=red
70 [label="Enter function test_5" style="filled" fillcolor=red];
71 [label="Access variable R|<local>/x|"];
72 [label="Enter safe call"];
73 [label="Postponed enter to lambda"];
subgraph cluster_12 {
color=blue
74 [label="Enter function anonymousFunction"];
75 [label="Jump: ^test_5 Unit"];
76 [label="Stub" style="filled" fillcolor=gray];
77 [label="Exit function anonymousFunction" style="filled" fillcolor=gray];
}
78 [label="Call arguments union" style="filled" fillcolor=gray];
79 [label="Postponed exit from lambda"];
80 [label="Function call: R|<local>/x|?.R|kotlin/let|<R|A|, R|kotlin/Nothing|>(...)" style="filled" fillcolor=gray];
81 [label="Exit safe call"];
82 [label="Enter safe call"];
83 [label="Access variable R|<local>/x|"];
84 [label="Function call: R|<local>/x|.R|/A.bool|()"];
85 [label="Function call: R|<local>/x|?.R|kotlin/let|<R|A|, R|kotlin/Nothing|>(...)?.R|/boo|(...)"];
86 [label="Exit safe call"];
87 [label="Access variable R|<local>/x|"];
88 [label="Function call: R|<local>/x|.<Inapplicable(WRONG_RECEIVER): [/A.id]>#()"];
89 [label="Exit function test_5" style="filled" fillcolor=red];
}
70 -> {71};
71 -> {72 81};
72 -> {73};
73 -> {74};
73 -> {79} [color=red];
74 -> {75};
75 -> {89};
75 -> {76} [style=dotted];
76 -> {77} [style=dotted];
77 -> {78} [style=dotted];
77 -> {79} [color=green];
78 -> {80} [style=dotted];
79 -> {80} [color=green];
80 -> {81} [style=dotted];
81 -> {82 86};
82 -> {83};
83 -> {84};
84 -> {85};
85 -> {86};
86 -> {87};
87 -> {88};
88 -> {89};
}
@@ -0,0 +1,38 @@
// !DUMP_CFG
fun String.foo(b: Boolean): String = ""
fun String.let(block: () -> Unit) {}
fun test(x: String?) {
x?.foo(x.length == 1)
x.<!INAPPLICABLE_CANDIDATE!>length<!>
}
interface A {
fun bar(a: A): String
fun bool(): Boolean
fun id(): A
}
fun test_2(x: Any) {
(x as? A)?.bar(x)
}
fun test_3(x: Any) {
(x as? A)?.bar(x)?.foo(x.bool())?.let {
x.bool()
}
x.<!UNRESOLVED_REFERENCE!>bool<!>()
}
fun test_4(x: A?) {
x?.id()?.bool()
x.<!INAPPLICABLE_CANDIDATE!>id<!>()
}
fun Any?.boo(b: Boolean)
fun test_5(x: A?) {
x?.let { return }?.boo(x.bool())
x.<!INAPPLICABLE_CANDIDATE!>id<!>()
}
@@ -0,0 +1,40 @@
FILE: safeCalls.kt
public final fun R|kotlin/String|.foo(b: R|kotlin/Boolean|): R|kotlin/String| {
^foo String()
}
public final fun R|kotlin/String|.let(block: R|() -> kotlin/Unit|): R|kotlin/Unit| {
}
public final fun test(x: R|kotlin/String?|): R|kotlin/Unit| {
R|<local>/x|?.R|/foo|(==(R|<local>/x|.R|kotlin/String.length|, Int(1)))
R|<local>/x|.<Inapplicable(WRONG_RECEIVER): [kotlin/String.length]>#
}
public abstract interface A : R|kotlin/Any| {
public abstract fun bar(a: R|A|): R|kotlin/String|
public abstract fun bool(): R|kotlin/Boolean|
public abstract fun id(): R|A|
}
public final fun test_2(x: R|kotlin/Any|): R|kotlin/Unit| {
(R|<local>/x| as? R|A|)?.R|/A.bar|(R|<local>/x|)
}
public final fun test_3(x: R|kotlin/Any|): R|kotlin/Unit| {
(R|<local>/x| as? R|A|)?.R|/A.bar|(R|<local>/x|)?.R|/foo|(R|<local>/x|.R|/A.bool|())?.R|/let|(<L> = let@fun <anonymous>(): R|kotlin/Unit| {
^ R|<local>/x|.R|/A.bool|()
}
)
R|<local>/x|.<Unresolved name: bool>#()
}
public final fun test_4(x: R|A?|): R|kotlin/Unit| {
R|<local>/x|?.R|/A.id|()?.R|/A.bool|()
R|<local>/x|.<Inapplicable(WRONG_RECEIVER): [/A.id]>#()
}
public final fun R|kotlin/Any?|.boo(b: R|kotlin/Boolean|): R|kotlin/Unit|
public final fun test_5(x: R|A?|): R|kotlin/Unit| {
R|<local>/x|?.R|kotlin/let|<R|A|, R|kotlin/Nothing|>(<L> = let@fun <anonymous>(it: R|A|): R|kotlin/Nothing| <kind=EXACTLY_ONCE> {
^test_5 Unit
}
)?.R|/boo|(R|<local>/x|.R|/A.bool|())
R|<local>/x|.<Inapplicable(WRONG_RECEIVER): [/A.id]>#()
}
@@ -0,0 +1,57 @@
digraph smartCastInInit_kt {
graph [nodesep=3]
node [shape=box penwidth=2]
edge [penwidth=2]
subgraph cluster_0 {
color=red
0 [label="Enter function foo" style="filled" fillcolor=red];
1 [label="Exit function foo" style="filled" fillcolor=red];
}
0 -> {1};
subgraph cluster_1 {
color=red
2 [label="Enter function s" style="filled" fillcolor=red];
3 [label="Function call: R|kotlin/TODO|()"];
4 [label="Stub" style="filled" fillcolor=gray];
5 [label="Jump: ^s R|kotlin/TODO|()" style="filled" fillcolor=gray];
6 [label="Stub" style="filled" fillcolor=gray];
7 [label="Exit function s" style="filled" fillcolor=red];
}
2 -> {3};
3 -> {7};
3 -> {4} [style=dotted];
4 -> {5} [style=dotted];
5 -> {7 6} [style=dotted];
6 -> {7} [style=dotted];
subgraph cluster_2 {
color=red
8 [label="Enter function <init>" style="filled" fillcolor=red];
9 [label="Delegated constructor call: super<R|kotlin/Any|>()"];
10 [label="Exit function <init>" style="filled" fillcolor=red];
}
8 -> {9};
9 -> {10};
subgraph cluster_3 {
color=red
11 [label="Enter function getter" style="filled" fillcolor=red];
12 [label="Exit function getter" style="filled" fillcolor=red];
}
11 -> {12};
subgraph cluster_4 {
color=red
13 [label="Enter property" style="filled" fillcolor=red];
14 [label="Exit property" style="filled" fillcolor=red];
}
13 -> {14};
}
@@ -0,0 +1,15 @@
// !DUMP_CFG
interface I
interface S : I {
fun foo()
}
fun s(): S = TODO()
class Main {
private val x: I
init {
x = s()
x.foo()
}
}
@@ -0,0 +1,24 @@
FILE: smartCastInInit.kt
public abstract interface I : R|kotlin/Any| {
}
public abstract interface S : R|I| {
public abstract fun foo(): R|kotlin/Unit|
}
public final fun s(): R|S| {
^s R|kotlin/TODO|()
}
public final class Main : R|kotlin/Any| {
public constructor(): R|Main| {
super<R|kotlin/Any|>()
}
private final val x: R|I|
private get(): R|I|
init {
this@R|/Main|.R|/Main.x| = R|/s|()
this@R|/Main|.R|/Main.x|.R|/S.foo|()
}
}
@@ -0,0 +1,278 @@
digraph smartcastToNothing_kt {
graph [nodesep=3]
node [shape=box penwidth=2]
edge [penwidth=2]
subgraph cluster_0 {
color=red
0 [label="Enter function getNothing" style="filled" fillcolor=red];
1 [label="Function call: R|java/lang/Exception.Exception|()"];
2 [label="Throw: throw R|java/lang/Exception.Exception|()"];
3 [label="Stub" style="filled" fillcolor=gray];
4 [label="Jump: ^getNothing throw R|java/lang/Exception.Exception|()" style="filled" fillcolor=gray];
5 [label="Stub" style="filled" fillcolor=gray];
6 [label="Exit function getNothing" style="filled" fillcolor=red];
}
0 -> {1};
1 -> {2};
2 -> {6};
2 -> {3} [style=dotted];
3 -> {4} [style=dotted];
4 -> {6 5} [style=dotted];
5 -> {6} [style=dotted];
subgraph cluster_1 {
color=red
7 [label="Enter function getNullableNothing" style="filled" fillcolor=red];
8 [label="Const: Null(null)"];
9 [label="Jump: ^getNullableNothing Null(null)"];
10 [label="Stub" style="filled" fillcolor=gray];
11 [label="Exit function getNullableNothing" style="filled" fillcolor=red];
}
7 -> {8};
8 -> {9};
9 -> {11};
9 -> {10} [style=dotted];
10 -> {11} [style=dotted];
subgraph cluster_2 {
color=red
12 [label="Enter function getter" style="filled" fillcolor=red];
13 [label="Const: Int(1)"];
14 [label="Jump: ^ Int(1)"];
15 [label="Stub" style="filled" fillcolor=gray];
16 [label="Exit function getter" style="filled" fillcolor=red];
}
12 -> {13};
13 -> {14};
14 -> {16};
14 -> {15} [style=dotted];
15 -> {16} [style=dotted];
subgraph cluster_3 {
color=red
17 [label="Enter property" style="filled" fillcolor=red];
18 [label="Exit property" style="filled" fillcolor=red];
}
17 -> {18};
subgraph cluster_4 {
color=red
19 [label="Enter function getter" style="filled" fillcolor=red];
20 [label="Const: Int(2)"];
21 [label="Jump: ^ Int(2)"];
22 [label="Stub" style="filled" fillcolor=gray];
23 [label="Exit function getter" style="filled" fillcolor=red];
}
19 -> {20};
20 -> {21};
21 -> {23};
21 -> {22} [style=dotted];
22 -> {23} [style=dotted];
subgraph cluster_5 {
color=red
24 [label="Enter property" style="filled" fillcolor=red];
25 [label="Exit property" style="filled" fillcolor=red];
}
24 -> {25};
subgraph cluster_6 {
color=red
26 [label="Enter function myListOf" style="filled" fillcolor=red];
27 [label="Const: Null(null)"];
28 [label="Check not null: Null(null)!!"];
29 [label="Jump: ^myListOf Null(null)!!"];
30 [label="Stub" style="filled" fillcolor=gray];
31 [label="Exit function myListOf" style="filled" fillcolor=red];
}
26 -> {27};
27 -> {28};
28 -> {29};
29 -> {31};
29 -> {30} [style=dotted];
30 -> {31} [style=dotted];
subgraph cluster_7 {
color=red
32 [label="Enter function <init>" style="filled" fillcolor=red];
33 [label="Delegated constructor call: super<R|kotlin/Any|>()"];
34 [label="Exit function <init>" style="filled" fillcolor=red];
}
32 -> {33};
33 -> {34};
subgraph cluster_8 {
color=red
35 [label="Enter function getter" style="filled" fillcolor=red];
36 [label="Exit function getter" style="filled" fillcolor=red];
}
35 -> {36};
subgraph cluster_9 {
color=red
37 [label="Enter property" style="filled" fillcolor=red];
38 [label="Const: Int(1)"];
39 [label="Exit property" style="filled" fillcolor=red];
}
37 -> {38};
38 -> {39};
subgraph cluster_10 {
color=red
40 [label="Enter function getter" style="filled" fillcolor=red];
41 [label="Exit function getter" style="filled" fillcolor=red];
}
40 -> {41};
subgraph cluster_11 {
color=red
42 [label="Enter property" style="filled" fillcolor=red];
43 [label="Const: Boolean(true)"];
44 [label="Exit property" style="filled" fillcolor=red];
}
42 -> {43};
43 -> {44};
subgraph cluster_12 {
color=red
45 [label="Enter function test_0" style="filled" fillcolor=red];
46 [label="Const: Null(null)"];
47 [label="Variable declaration: lvar s: R|A?|"];
48 [label="Access variable R|<local>/results|"];
49 [label="Function call: R|<local>/results|.R|FakeOverride<kotlin/collections/List.iterator: R|kotlin/collections/Iterator<kotlin/Nothing>|>|()"];
50 [label="Variable declaration: lval <iterator>: R|kotlin/collections/Iterator<kotlin/Nothing>|"];
subgraph cluster_13 {
color=blue
51 [label="Enter while loop"];
subgraph cluster_14 {
color=blue
52 [label="Enter loop condition"];
53 [label="Access variable R|<local>/<iterator>|"];
54 [label="Function call: R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()"];
55 [label="Exit loop condition"];
}
subgraph cluster_15 {
color=blue
56 [label="Enter loop block"];
subgraph cluster_16 {
color=blue
57 [label="Enter block"];
58 [label="Access variable R|<local>/<iterator>|"];
59 [label="Function call: R|<local>/<iterator>|.R|FakeOverride<kotlin/collections/Iterator.next: R|kotlin/Nothing|>|()"];
60 [label="Stub" style="filled" fillcolor=gray];
61 [label="Variable declaration: lval result: R|kotlin/Nothing|" style="filled" fillcolor=gray];
62 [label="Access variable R|<local>/result|" style="filled" fillcolor=gray];
63 [label="Stub" style="filled" fillcolor=gray];
64 [label="Assignmenet: R|<local>/s|" style="filled" fillcolor=gray];
subgraph cluster_17 {
color=blue
65 [label="Enter when" style="filled" fillcolor=gray];
subgraph cluster_18 {
color=blue
66 [label="Enter when branch condition " style="filled" fillcolor=gray];
67 [label="Access variable R|<local>/result|" style="filled" fillcolor=gray];
68 [label="Stub" style="filled" fillcolor=gray];
69 [label="Access variable <Unresolved name: b>#" style="filled" fillcolor=gray];
70 [label="Exit when branch condition" style="filled" fillcolor=gray];
}
71 [label="Synthetic else branch" style="filled" fillcolor=gray];
72 [label="Enter when branch result" style="filled" fillcolor=gray];
subgraph cluster_19 {
color=blue
73 [label="Enter block" style="filled" fillcolor=gray];
74 [label="Jump: break@@@[R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()] " style="filled" fillcolor=gray];
75 [label="Stub" style="filled" fillcolor=gray];
76 [label="Exit block" style="filled" fillcolor=gray];
}
77 [label="Exit when branch result" style="filled" fillcolor=gray];
78 [label="Exit when" style="filled" fillcolor=gray];
}
79 [label="Exit block" style="filled" fillcolor=gray];
}
80 [label="Exit loop block" style="filled" fillcolor=gray];
}
81 [label="Exit whileloop"];
}
82 [label="Access variable R|<local>/s|"];
83 [label="Enter safe call"];
84 [label="Postponed enter to lambda"];
subgraph cluster_20 {
color=blue
85 [label="Enter function anonymousFunction"];
86 [label="Access variable R|<local>/it|"];
87 [label="Access variable R|/A.a|"];
88 [label="Exit function anonymousFunction"];
}
89 [label="Call arguments union" style="filled" fillcolor=yellow];
90 [label="Postponed exit from lambda"];
91 [label="Function call: R|<local>/s|?.R|kotlin/let|<R|A|, R|kotlin/Int|>(...)"];
92 [label="Exit safe call"];
93 [label="Exit function test_0" style="filled" fillcolor=red];
}
45 -> {46};
46 -> {47};
47 -> {48};
48 -> {49};
49 -> {50};
50 -> {51};
51 -> {52};
52 -> {53};
53 -> {54};
54 -> {55};
55 -> {81 56};
56 -> {57};
57 -> {58};
58 -> {59};
59 -> {93};
59 -> {60} [style=dotted];
60 -> {61} [style=dotted];
61 -> {62} [style=dotted];
62 -> {93 63} [style=dotted];
63 -> {64} [style=dotted];
64 -> {65} [style=dotted];
65 -> {66} [style=dotted];
66 -> {67} [style=dotted];
67 -> {93 68} [style=dotted];
68 -> {69} [style=dotted];
69 -> {70} [style=dotted];
70 -> {72 71} [style=dotted];
71 -> {78} [style=dotted];
72 -> {73} [style=dotted];
73 -> {74} [style=dotted];
74 -> {81 75} [style=dotted];
75 -> {76} [style=dotted];
76 -> {77} [style=dotted];
77 -> {78} [style=dotted];
78 -> {79} [style=dotted];
79 -> {80} [style=dotted];
80 -> {52} [style=dotted];
81 -> {82};
82 -> {83 92};
83 -> {84};
84 -> {85};
84 -> {90} [color=red];
85 -> {86};
86 -> {87};
87 -> {88};
88 -> {90} [color=green];
88 -> {89} [color=red];
89 -> {91} [color=red];
90 -> {91} [color=green];
91 -> {92};
92 -> {93} [style=dotted];
}
@@ -0,0 +1,24 @@
// !DUMP_CFG
fun getNothing(): Nothing = throw Exception()
fun getNullableNothing(): Nothing? = null
val String?.q: Int get() = 1
val String.qq: Int get() = 2
fun <T> myListOf(x: T): List<T> = null!!
class A {
val a: Int = 1
val b: Boolean = true
}
fun test_0(results: List<Nothing>) {
var s: A? = null
for (result in results) {
s = result
if (result.<!UNRESOLVED_REFERENCE!>b<!>) {
break
}
}
s?.let { it.a }
}
@@ -0,0 +1,49 @@
FILE: smartcastToNothing.kt
public final fun getNothing(): R|kotlin/Nothing| {
^getNothing throw R|java/lang/Exception.Exception|()
}
public final fun getNullableNothing(): R|kotlin/Nothing?| {
^getNullableNothing Null(null)
}
public final val R|kotlin/String?|.q: R|kotlin/Int|
public get(): R|kotlin/Int| {
^ Int(1)
}
public final val R|kotlin/String|.qq: R|kotlin/Int|
public get(): R|kotlin/Int| {
^ Int(2)
}
public final fun <T> myListOf(x: R|T|): R|kotlin/collections/List<T>| {
^myListOf Null(null)!!
}
public final class A : R|kotlin/Any| {
public constructor(): R|A| {
super<R|kotlin/Any|>()
}
public final val a: R|kotlin/Int| = Int(1)
public get(): R|kotlin/Int|
public final val b: R|kotlin/Boolean| = Boolean(true)
public get(): R|kotlin/Boolean|
}
public final fun test_0(results: R|kotlin/collections/List<kotlin/Nothing>|): R|kotlin/Unit| {
lvar s: R|A?| = Null(null)
lval <iterator>: R|kotlin/collections/Iterator<kotlin/Nothing>| = R|<local>/results|.R|FakeOverride<kotlin/collections/List.iterator: R|kotlin/collections/Iterator<kotlin/Nothing>|>|()
while(R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()) {
lval result: R|kotlin/Nothing| = R|<local>/<iterator>|.R|FakeOverride<kotlin/collections/Iterator.next: R|kotlin/Nothing|>|()
R|<local>/s| = R|<local>/result|
when () {
R|<local>/result|.<Unresolved name: b># -> {
break@@@[R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()]
}
}
}
R|<local>/s|?.R|kotlin/let|<R|A|, R|kotlin/Int|>(<L> = let@fun <anonymous>(it: R|A|): R|kotlin/Int| <kind=EXACTLY_ONCE> {
^ R|<local>/it|.R|/A.a|
}
)
}
@@ -0,0 +1,136 @@
digraph overridenOpenVal_kt {
graph [nodesep=3]
node [shape=box penwidth=2]
edge [penwidth=2]
subgraph cluster_0 {
color=red
0 [label="Enter function <init>" style="filled" fillcolor=red];
1 [label="Delegated constructor call: super<R|kotlin/Any|>()"];
2 [label="Exit function <init>" style="filled" fillcolor=red];
}
0 -> {1};
1 -> {2};
subgraph cluster_1 {
color=red
3 [label="Enter function getter" style="filled" fillcolor=red];
4 [label="Exit function getter" style="filled" fillcolor=red];
}
3 -> {4};
subgraph cluster_2 {
color=red
5 [label="Enter property" style="filled" fillcolor=red];
6 [label="Access variable R|<local>/x|"];
7 [label="Exit property" style="filled" fillcolor=red];
}
5 -> {6};
6 -> {7};
subgraph cluster_3 {
color=red
8 [label="Enter function <init>" style="filled" fillcolor=red];
9 [label="Access variable R|<local>/x|"];
10 [label="Delegated constructor call: super<R|A|>(...)"];
11 [label="Exit function <init>" style="filled" fillcolor=red];
}
8 -> {9};
9 -> {10};
10 -> {11};
subgraph cluster_4 {
color=red
12 [label="Enter function test_1" style="filled" fillcolor=red];
subgraph cluster_5 {
color=blue
13 [label="Enter when"];
subgraph cluster_6 {
color=blue
14 [label="Enter when branch condition "];
15 [label="Access variable R|/A.x|"];
16 [label="Type operator: (this@R|/B|.R|/A.x| is R|kotlin/String|)"];
17 [label="Exit when branch condition"];
}
18 [label="Synthetic else branch"];
19 [label="Enter when branch result"];
subgraph cluster_7 {
color=blue
20 [label="Enter block"];
21 [label="Access variable R|/A.x|"];
22 [label="Access variable R|kotlin/String.length|"];
23 [label="Exit block"];
}
24 [label="Exit when branch result"];
25 [label="Exit when"];
}
26 [label="Exit function test_1" style="filled" fillcolor=red];
}
12 -> {13};
13 -> {14};
14 -> {15};
15 -> {16};
16 -> {17};
17 -> {19 18};
18 -> {25};
19 -> {20};
20 -> {21};
21 -> {22};
22 -> {23};
23 -> {24};
24 -> {25};
25 -> {26};
subgraph cluster_8 {
color=red
27 [label="Enter function test_2" style="filled" fillcolor=red];
subgraph cluster_9 {
color=blue
28 [label="Enter when"];
subgraph cluster_10 {
color=blue
29 [label="Enter when branch condition "];
30 [label="Access variable R|<local>/b|"];
31 [label="Access variable R|/A.x|"];
32 [label="Type operator: (R|<local>/b|.R|/A.x| is R|kotlin/String|)"];
33 [label="Exit when branch condition"];
}
34 [label="Synthetic else branch"];
35 [label="Enter when branch result"];
subgraph cluster_11 {
color=blue
36 [label="Enter block"];
37 [label="Access variable R|<local>/b|"];
38 [label="Access variable R|/A.x|"];
39 [label="Access variable R|kotlin/String.length|"];
40 [label="Exit block"];
}
41 [label="Exit when branch result"];
42 [label="Exit when"];
}
43 [label="Exit function test_2" style="filled" fillcolor=red];
}
27 -> {28};
28 -> {29};
29 -> {30};
30 -> {31};
31 -> {32};
32 -> {33};
33 -> {35 34};
34 -> {42};
35 -> {36};
36 -> {37};
37 -> {38};
38 -> {39};
39 -> {40};
40 -> {41};
41 -> {42};
42 -> {43};
}
@@ -0,0 +1,16 @@
// !DUMP_CFG
open class A(open val x: Any)
class B(x: Any) : A(x) {
fun test_1() {
if (x is String) {
x.length
}
}
}
fun test_2(b: B) {
if (b.x is String) {
b.x.length
}
}
@@ -0,0 +1,33 @@
FILE: overridenOpenVal.kt
public open class A : R|kotlin/Any| {
public constructor(x: R|kotlin/Any|): R|A| {
super<R|kotlin/Any|>()
}
public open val x: R|kotlin/Any| = R|<local>/x|
public get(): R|kotlin/Any|
}
public final class B : R|A| {
public constructor(x: R|kotlin/Any|): R|B| {
super<R|A|>(R|<local>/x|)
}
public final fun test_1(): R|kotlin/Unit| {
when () {
(this@R|/B|.R|/A.x| is R|kotlin/String|) -> {
this@R|/B|.R|/A.x|.R|kotlin/String.length|
}
}
}
}
public final fun test_2(b: R|B|): R|kotlin/Unit| {
when () {
(R|<local>/b|.R|/A.x| is R|kotlin/String|) -> {
R|<local>/b|.R|/A.x|.R|kotlin/String.length|
}
}
}
@@ -0,0 +1,95 @@
digraph delayedAssignment_kt {
graph [nodesep=3]
node [shape=box penwidth=2]
edge [penwidth=2]
subgraph cluster_0 {
color=red
0 [label="Enter function <init>" style="filled" fillcolor=red];
1 [label="Delegated constructor call: super<R|kotlin/Any|>()"];
2 [label="Exit function <init>" style="filled" fillcolor=red];
}
0 -> {1};
1 -> {2};
subgraph cluster_1 {
color=red
3 [label="Enter function foo" style="filled" fillcolor=red];
4 [label="Exit function foo" style="filled" fillcolor=red];
}
3 -> {4};
subgraph cluster_2 {
color=red
5 [label="Enter function test" style="filled" fillcolor=red];
6 [label="Variable declaration: lval a: R|A?|"];
subgraph cluster_3 {
color=blue
7 [label="Enter when"];
subgraph cluster_4 {
color=blue
8 [label="Enter when branch condition "];
9 [label="Access variable R|<local>/b|"];
10 [label="Exit when branch condition"];
}
subgraph cluster_5 {
color=blue
11 [label="Enter when branch condition else"];
12 [label="Exit when branch condition"];
}
13 [label="Enter when branch result"];
subgraph cluster_6 {
color=blue
14 [label="Enter block"];
15 [label="Const: Null(null)"];
16 [label="Assignmenet: R|<local>/a|"];
17 [label="Exit block"];
}
18 [label="Exit when branch result"];
19 [label="Enter when branch result"];
subgraph cluster_7 {
color=blue
20 [label="Enter block"];
21 [label="Function call: R|/A.A|()"];
22 [label="Assignmenet: R|<local>/a|"];
23 [label="Access variable R|<local>/a|"];
24 [label="Function call: R|<local>/a|.R|/A.foo|()"];
25 [label="Exit block"];
}
26 [label="Exit when branch result"];
27 [label="Exit when"];
}
28 [label="Access variable R|<local>/a|"];
29 [label="Function call: R|<local>/a|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()"];
30 [label="Exit function test" style="filled" fillcolor=red];
}
5 -> {6};
6 -> {7};
7 -> {8};
8 -> {9};
9 -> {10};
10 -> {19 11};
11 -> {12};
12 -> {13};
13 -> {14};
14 -> {15};
15 -> {16};
16 -> {17};
17 -> {18};
18 -> {27};
19 -> {20};
20 -> {21};
21 -> {22};
22 -> {23};
23 -> {24};
24 -> {25};
25 -> {26};
26 -> {27};
27 -> {28};
28 -> {29};
29 -> {30};
}
@@ -0,0 +1,15 @@
// !DUMP_CFG
class A {
fun foo() {}
}
fun test(b: Boolean) {
val a: A?
if (b) {
a = A()
a.foo()
} else {
a = null
}
a.<!INAPPLICABLE_CANDIDATE!>foo<!>()
}
@@ -0,0 +1,24 @@
FILE: delayedAssignment.kt
public final class A : R|kotlin/Any| {
public constructor(): R|A| {
super<R|kotlin/Any|>()
}
public final fun foo(): R|kotlin/Unit| {
}
}
public final fun test(b: R|kotlin/Boolean|): R|kotlin/Unit| {
lval a: R|A?|
when () {
R|<local>/b| -> {
R|<local>/a| = R|/A.A|()
R|<local>/a|.R|/A.foo|()
}
else -> {
R|<local>/a| = Null(null)
}
}
R|<local>/a|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()
}
@@ -0,0 +1,107 @@
digraph smartcastAfterReassignment_kt {
graph [nodesep=3]
node [shape=box penwidth=2]
edge [penwidth=2]
subgraph cluster_0 {
color=red
0 [label="Enter function test_1" style="filled" fillcolor=red];
1 [label="Const: Int(1)"];
2 [label="Variable declaration: lvar x: R|kotlin/Any|"];
3 [label="Const: String()"];
4 [label="Assignmenet: R|<local>/x|"];
5 [label="Access variable R|<local>/x|"];
6 [label="Access variable R|kotlin/String.length|"];
7 [label="Exit function test_1" style="filled" fillcolor=red];
}
0 -> {1};
1 -> {2};
2 -> {3};
3 -> {4};
4 -> {5};
5 -> {6};
6 -> {7};
subgraph cluster_1 {
color=red
8 [label="Enter function test_2" style="filled" fillcolor=red];
9 [label="Const: Null(null)"];
10 [label="Variable declaration: lvar x: R|kotlin/String?|"];
subgraph cluster_2 {
color=blue
11 [label="Enter when"];
subgraph cluster_3 {
color=blue
12 [label="Enter when branch condition "];
13 [label="Access variable R|<local>/x|"];
14 [label="Const: Null(null)"];
15 [label="Operator =="];
16 [label="Exit when branch condition"];
}
17 [label="Synthetic else branch"];
18 [label="Enter when branch result"];
subgraph cluster_4 {
color=blue
19 [label="Enter block"];
20 [label="Const: String()"];
21 [label="Assignmenet: R|<local>/x|"];
22 [label="Exit block"];
}
23 [label="Exit when branch result"];
24 [label="Exit when"];
}
25 [label="Access variable R|<local>/x|"];
26 [label="Access variable R|kotlin/String.length|"];
27 [label="Exit function test_2" style="filled" fillcolor=red];
}
8 -> {9};
9 -> {10};
10 -> {11};
11 -> {12};
12 -> {13};
13 -> {14};
14 -> {15};
15 -> {16};
16 -> {18 17};
17 -> {24};
18 -> {19};
19 -> {20};
20 -> {21};
21 -> {22};
22 -> {23};
23 -> {24};
24 -> {25};
25 -> {26};
26 -> {27};
subgraph cluster_5 {
color=red
28 [label="Enter function test_3" style="filled" fillcolor=red];
29 [label="Const: Null(null)"];
30 [label="Variable declaration: lvar x: R|kotlin/String?|"];
31 [label="Const: String()"];
32 [label="Assignmenet: R|<local>/x|"];
33 [label="Access variable R|<local>/x|"];
34 [label="Access variable R|kotlin/String.length|"];
35 [label="Const: Null(null)"];
36 [label="Assignmenet: R|<local>/x|"];
37 [label="Access variable R|<local>/x|"];
38 [label="Access variable <Inapplicable(WRONG_RECEIVER): [kotlin/String.length]>#"];
39 [label="Exit function test_3" style="filled" fillcolor=red];
}
28 -> {29};
29 -> {30};
30 -> {31};
31 -> {32};
32 -> {33};
33 -> {34};
34 -> {35};
35 -> {36};
36 -> {37};
37 -> {38};
38 -> {39};
}
@@ -0,0 +1,22 @@
// !DUMP_CFG
fun test_1() {
var x: Any = 1
x = ""
x.length
}
fun test_2() {
var x: String? = null
if (x == null) {
x = ""
}
x.length
}
fun test_3() {
var x: String? = null
x = ""
x.length
x = null
x.<!INAPPLICABLE_CANDIDATE!>length<!>
}

Some files were not shown because too many files have changed in this diff Show More