[FIR-TEST] Reorganize tests for data flow analysis

This commit is contained in:
Dmitriy Novozhilov
2020-02-12 12:17:58 +03:00
parent 89fa3572ec
commit 90021f3ece
78 changed files with 1324 additions and 1190 deletions
@@ -1,503 +0,0 @@
digraph booleanOperators_kt {
graph [splines=ortho nodesep=3]
node [shape=box penwidth=2]
edge [penwidth=2]
subgraph cluster_0 {
color=red
0 [label="Enter function foo" style="filled" fillcolor=red];
1 [label="Exit function foo" style="filled" fillcolor=red];
}
0 -> {1};
subgraph cluster_1 {
color=red
2 [label="Enter function bool" style="filled" fillcolor=red];
3 [label="Exit function bool" style="filled" fillcolor=red];
}
2 -> {3};
subgraph cluster_2 {
color=red
4 [label="Enter function bar" style="filled" fillcolor=red];
5 [label="Exit function bar" style="filled" fillcolor=red];
}
4 -> {5};
subgraph cluster_3 {
color=red
6 [label="Enter function baz" style="filled" fillcolor=red];
7 [label="Exit function baz" style="filled" fillcolor=red];
}
6 -> {7};
subgraph cluster_4 {
color=red
8 [label="Enter function test_1" style="filled" fillcolor=red];
subgraph cluster_5 {
color=blue
9 [label="Enter when"];
subgraph cluster_6 {
color=blue
10 [label="Enter when branch condition "];
subgraph cluster_7 {
color=blue
11 [label="Enter &&"];
12 [label="Access variable R|<local>/x|"];
13 [label="Type operator: x is B"];
14 [label="Exit left part of &&"];
15 [label="Enter right part of &&"];
16 [label="Access variable R|<local>/x|"];
17 [label="Type operator: x is C"];
18 [label="Exit &&"];
}
19 [label="Exit when branch condition"];
}
20 [label="Synthetic else branch"];
21 [label="Enter when branch result"];
subgraph cluster_8 {
color=blue
22 [label="Enter block"];
23 [label="Access variable R|<local>/x|"];
24 [label="Function call: R|<local>/x|.R|/A.foo|()"];
25 [label="Access variable R|<local>/x|"];
26 [label="Function call: R|<local>/x|.R|/B.bar|()"];
27 [label="Access variable R|<local>/x|"];
28 [label="Function call: R|<local>/x|.R|/C.baz|()"];
29 [label="Exit block"];
}
30 [label="Exit when branch result"];
31 [label="Exit when"];
}
32 [label="Exit function test_1" style="filled" fillcolor=red];
}
8 -> {9};
9 -> {10};
10 -> {11};
11 -> {12};
12 -> {13};
13 -> {14};
14 -> {18 15};
15 -> {16};
16 -> {17};
17 -> {18};
18 -> {19};
19 -> {21 20};
20 -> {31};
21 -> {22};
22 -> {23};
23 -> {24};
24 -> {25};
25 -> {26};
26 -> {27};
27 -> {28};
28 -> {29};
29 -> {30};
30 -> {31};
31 -> {32};
subgraph cluster_9 {
color=red
33 [label="Enter function test_2" style="filled" fillcolor=red];
subgraph cluster_10 {
color=blue
34 [label="Enter when"];
subgraph cluster_11 {
color=blue
35 [label="Enter when branch condition "];
subgraph cluster_12 {
color=blue
36 [label="Enter ||"];
37 [label="Access variable R|<local>/x|"];
38 [label="Type operator: x is B"];
39 [label="Exit left part of ||"];
40 [label="Enter right part of ||"];
41 [label="Access variable R|<local>/x|"];
42 [label="Type operator: x is C"];
43 [label="Exit ||"];
}
44 [label="Exit when branch condition"];
}
45 [label="Synthetic else branch"];
46 [label="Enter when branch result"];
subgraph cluster_13 {
color=blue
47 [label="Enter block"];
48 [label="Access variable R|<local>/x|"];
49 [label="Function call: R|<local>/x|.R|/A.foo|()"];
50 [label="Access variable R|<local>/x|"];
51 [label="Function call: R|<local>/x|.<Unresolved name: bar>#()"];
52 [label="Access variable R|<local>/x|"];
53 [label="Function call: R|<local>/x|.<Unresolved name: baz>#()"];
54 [label="Exit block"];
}
55 [label="Exit when branch result"];
56 [label="Exit when"];
}
57 [label="Exit function test_2" style="filled" fillcolor=red];
}
33 -> {34};
34 -> {35};
35 -> {36};
36 -> {37};
37 -> {38};
38 -> {39};
39 -> {43 40};
40 -> {41};
41 -> {42};
42 -> {43};
43 -> {44};
44 -> {46 45};
45 -> {56};
46 -> {47};
47 -> {48};
48 -> {49};
49 -> {50};
50 -> {51};
51 -> {52};
52 -> {53};
53 -> {54};
54 -> {55};
55 -> {56};
56 -> {57};
subgraph cluster_14 {
color=red
58 [label="Enter function test_3" style="filled" fillcolor=red];
subgraph cluster_15 {
color=blue
59 [label="Enter when"];
subgraph cluster_16 {
color=blue
60 [label="Enter when branch condition "];
61 [label="Access variable R|<local>/x|"];
62 [label="Type operator: x !is A"];
63 [label="Function call: (R|<local>/x| !is R|A|).R|kotlin/Boolean.not|()"];
64 [label="Exit when branch condition"];
}
65 [label="Synthetic else branch"];
66 [label="Enter when branch result"];
subgraph cluster_17 {
color=blue
67 [label="Enter block"];
68 [label="Access variable R|<local>/x|"];
69 [label="Function call: R|<local>/x|.R|/A.foo|()"];
70 [label="Exit block"];
}
71 [label="Exit when branch result"];
72 [label="Exit when"];
}
73 [label="Exit function test_3" style="filled" fillcolor=red];
}
58 -> {59};
59 -> {60};
60 -> {61};
61 -> {62};
62 -> {63};
63 -> {64};
64 -> {66 65};
65 -> {72};
66 -> {67};
67 -> {68};
68 -> {69};
69 -> {70};
70 -> {71};
71 -> {72};
72 -> {73};
subgraph cluster_18 {
color=red
74 [label="Enter function test_4" style="filled" fillcolor=red];
subgraph cluster_19 {
color=blue
75 [label="Enter when"];
subgraph cluster_20 {
color=blue
76 [label="Enter when branch condition "];
subgraph cluster_21 {
color=blue
77 [label="Enter ||"];
78 [label="Access variable R|<local>/x|"];
79 [label="Type operator: x !is String"];
80 [label="Exit left part of ||"];
81 [label="Enter right part of ||"];
82 [label="Access variable R|<local>/x|"];
83 [label="Access variable R|kotlin/String.length|"];
84 [label="Const: Int(0)"];
85 [label="Operator =="];
86 [label="Exit ||"];
}
87 [label="Exit when branch condition"];
}
88 [label="Synthetic else branch"];
89 [label="Enter when branch result"];
subgraph cluster_22 {
color=blue
90 [label="Enter block"];
91 [label="Access variable R|<local>/x|"];
92 [label="Access variable <Unresolved name: length>#"];
93 [label="Exit block"];
}
94 [label="Exit when branch result"];
95 [label="Exit when"];
}
96 [label="Access variable R|<local>/x|"];
97 [label="Access variable <Unresolved name: length>#"];
98 [label="Exit function test_4" style="filled" fillcolor=red];
}
74 -> {75};
75 -> {76};
76 -> {77};
77 -> {78};
78 -> {79};
79 -> {80};
80 -> {86 81};
81 -> {82};
82 -> {83};
83 -> {84};
84 -> {85};
85 -> {86};
86 -> {87};
87 -> {89 88};
88 -> {95};
89 -> {90};
90 -> {91};
91 -> {92};
92 -> {93};
93 -> {94};
94 -> {95};
95 -> {96};
96 -> {97};
97 -> {98};
subgraph cluster_23 {
color=red
99 [label="Enter function test_5" style="filled" fillcolor=red];
subgraph cluster_24 {
color=blue
100 [label="Enter when"];
subgraph cluster_25 {
color=blue
101 [label="Enter when branch condition "];
subgraph cluster_26 {
color=blue
102 [label="Enter ||"];
103 [label="Access variable R|<local>/x|"];
104 [label="Const: Null(null)"];
105 [label="Operator !="];
106 [label="Exit left part of ||"];
107 [label="Enter right part of ||"];
108 [label="Const: Boolean(false)"];
109 [label="Exit ||"];
}
110 [label="Exit when branch condition"];
}
111 [label="Synthetic else branch"];
112 [label="Enter when branch result"];
subgraph cluster_27 {
color=blue
113 [label="Enter block"];
114 [label="Access variable R|<local>/x|"];
115 [label="Function call: R|<local>/x|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()"];
116 [label="Exit block"];
}
117 [label="Exit when branch result"];
118 [label="Exit when"];
}
119 [label="Exit function test_5" style="filled" fillcolor=red];
}
99 -> {100};
100 -> {101};
101 -> {102};
102 -> {103};
103 -> {104};
104 -> {105};
105 -> {106};
106 -> {109 107};
107 -> {108};
108 -> {109};
109 -> {110};
110 -> {112 111};
111 -> {118};
112 -> {113};
113 -> {114};
114 -> {115};
115 -> {116};
116 -> {117};
117 -> {118};
118 -> {119};
subgraph cluster_28 {
color=red
120 [label="Enter function test_6" style="filled" fillcolor=red];
subgraph cluster_29 {
color=blue
121 [label="Enter when"];
subgraph cluster_30 {
color=blue
122 [label="Enter when branch condition "];
subgraph cluster_31 {
color=blue
123 [label="Enter ||"];
124 [label="Const: Boolean(false)"];
125 [label="Exit left part of ||"];
126 [label="Enter right part of ||"];
127 [label="Access variable R|<local>/x|"];
128 [label="Const: Null(null)"];
129 [label="Operator !="];
130 [label="Stub" style="filled" fillcolor=gray];
131 [label="Exit ||"];
}
132 [label="Exit when branch condition"];
}
133 [label="Synthetic else branch"];
134 [label="Enter when branch result"];
subgraph cluster_32 {
color=blue
135 [label="Enter block"];
136 [label="Access variable R|<local>/x|"];
137 [label="Function call: R|<local>/x|.<Inapplicable(WRONG_RECEIVER): [/A.foo]>#()"];
138 [label="Exit block"];
}
139 [label="Exit when branch result"];
140 [label="Exit when"];
}
141 [label="Exit function test_6" style="filled" fillcolor=red];
}
120 -> {121};
121 -> {122};
122 -> {123};
123 -> {124};
124 -> {125};
125 -> {126};
125 -> {130} [style=dotted];
126 -> {127};
127 -> {128};
128 -> {129};
129 -> {131};
130 -> {131} [style=dotted];
131 -> {132};
132 -> {134 133};
133 -> {140};
134 -> {135};
135 -> {136};
136 -> {137};
137 -> {138};
138 -> {139};
139 -> {140};
140 -> {141};
subgraph cluster_33 {
color=red
142 [label="Enter function test_7" style="filled" fillcolor=red];
subgraph cluster_34 {
color=blue
143 [label="Enter when"];
subgraph cluster_35 {
color=blue
144 [label="Enter when branch condition "];
subgraph cluster_36 {
color=blue
145 [label="Enter &&"];
146 [label="Access variable R|<local>/x|"];
147 [label="Type operator: x is A"];
148 [label="Exit left part of &&"];
149 [label="Enter right part of &&"];
150 [label="Access variable R|<local>/x|"];
151 [label="Function call: R|<local>/x|.R|/A.bool|()"];
152 [label="Exit &&"];
}
153 [label="Exit when branch condition"];
}
154 [label="Synthetic else branch"];
155 [label="Enter when branch result"];
subgraph cluster_37 {
color=blue
156 [label="Enter block"];
157 [label="Access variable R|<local>/x|"];
158 [label="Function call: R|<local>/x|.R|/A.foo|()"];
159 [label="Exit block"];
}
160 [label="Exit when branch result"];
161 [label="Exit when"];
}
162 [label="Exit function test_7" style="filled" fillcolor=red];
}
142 -> {143};
143 -> {144};
144 -> {145};
145 -> {146};
146 -> {147};
147 -> {148};
148 -> {152 149};
149 -> {150};
150 -> {151};
151 -> {152};
152 -> {153};
153 -> {155 154};
154 -> {161};
155 -> {156};
156 -> {157};
157 -> {158};
158 -> {159};
159 -> {160};
160 -> {161};
161 -> {162};
subgraph cluster_38 {
color=red
163 [label="Enter function test_8" style="filled" fillcolor=red];
subgraph cluster_39 {
color=blue
164 [label="Enter when"];
subgraph cluster_40 {
color=blue
165 [label="Enter when branch condition "];
166 [label="Access variable R|<local>/x|"];
167 [label="Type operator: x !is A"];
168 [label="Function call: (R|<local>/x| !is R|A|).R|kotlin/Boolean.not|()"];
169 [label="Exit when branch condition"];
}
170 [label="Synthetic else branch"];
171 [label="Enter when branch result"];
subgraph cluster_41 {
color=blue
172 [label="Enter block"];
173 [label="Access variable R|<local>/x|"];
174 [label="Function call: R|<local>/x|.R|/A.foo|()"];
175 [label="Exit block"];
}
176 [label="Exit when branch result"];
177 [label="Exit when"];
}
178 [label="Exit function test_8" style="filled" fillcolor=red];
}
163 -> {164};
164 -> {165};
165 -> {166};
166 -> {167};
167 -> {168};
168 -> {169};
169 -> {171 170};
170 -> {177};
171 -> {172};
172 -> {173};
173 -> {174};
174 -> {175};
175 -> {176};
176 -> {177};
177 -> {178};
}
@@ -278,4 +278,204 @@ digraph boundSmartcasts_kt {
100 -> {101};
101 -> {102};
subgraph cluster_21 {
color=red
103 [label="Enter function <init>" style="filled" fillcolor=red];
104 [label="Exit function <init>" style="filled" fillcolor=red];
}
103 -> {104};
subgraph cluster_22 {
color=red
105 [label="Enter function getter" style="filled" fillcolor=red];
106 [label="Exit function getter" style="filled" fillcolor=red];
}
105 -> {106};
subgraph cluster_23 {
color=red
107 [label="Enter property" style="filled" fillcolor=red];
108 [label="Access variable R|<local>/any|"];
109 [label="Exit property" style="filled" fillcolor=red];
}
107 -> {108};
108 -> {109};
subgraph cluster_24 {
color=red
110 [label="Enter function baz" style="filled" fillcolor=red];
111 [label="Exit function baz" style="filled" fillcolor=red];
}
110 -> {111};
subgraph cluster_25 {
color=red
112 [label="Enter function test_5" style="filled" fillcolor=red];
subgraph cluster_26 {
color=blue
113 [label="Enter when"];
114 [label="Access variable R|<local>/d|"];
115 [label="Access variable R|/D.any|"];
116 [label="Variable declaration: lval <elvis>: R|kotlin/Any?|"];
subgraph cluster_27 {
color=blue
117 [label="Enter when branch condition "];
118 [label="Const: Null(null)"];
119 [label="Operator =="];
120 [label="Exit when branch condition"];
}
subgraph cluster_28 {
color=blue
121 [label="Enter when branch condition else"];
122 [label="Exit when branch condition"];
}
123 [label="Enter when branch result"];
subgraph cluster_29 {
color=blue
124 [label="Enter block"];
125 [label="Access variable R|<local>/<elvis>|"];
126 [label="Exit block"];
}
127 [label="Exit when branch result"];
128 [label="Enter when branch result"];
subgraph cluster_30 {
color=blue
129 [label="Enter block"];
130 [label="Jump: ^test_5 Unit"];
131 [label="Stub" style="filled" fillcolor=gray];
132 [label="Exit block" style="filled" fillcolor=gray];
}
133 [label="Exit when branch result" style="filled" fillcolor=gray];
134 [label="Exit when"];
}
135 [label="Variable declaration: lval a: R|kotlin/Any|"];
136 [label="Access variable R|<local>/a|"];
137 [label="Function call: R|<local>/a|.R|/baz|()"];
138 [label="Access variable R|<local>/d|"];
139 [label="Access variable R|/D.any|"];
140 [label="Function call: R|<local>/d|.R|/D.any|.R|/baz|()"];
141 [label="Access variable R|<local>/a|"];
142 [label="Type operator: a as A"];
143 [label="Access variable R|<local>/a|"];
144 [label="Function call: R|<local>/a|.R|/A.foo|()"];
145 [label="Exit function test_5" style="filled" fillcolor=red];
}
112 -> {113};
113 -> {114};
114 -> {115};
115 -> {116};
116 -> {117};
117 -> {118};
118 -> {119};
119 -> {120};
120 -> {128 121};
121 -> {122};
122 -> {123};
123 -> {124};
124 -> {125};
125 -> {126};
126 -> {127};
127 -> {134};
128 -> {129};
129 -> {130};
130 -> {145};
130 -> {131} [style=dotted];
131 -> {132} [style=dotted];
132 -> {133} [style=dotted];
133 -> {134} [style=dotted];
134 -> {135};
135 -> {136};
136 -> {137};
137 -> {138};
138 -> {139};
139 -> {140};
140 -> {141};
141 -> {142};
142 -> {143};
143 -> {144};
144 -> {145};
subgraph cluster_31 {
color=red
146 [label="Enter function test_6" style="filled" fillcolor=red];
147 [label="Access variable R|<local>/d1|"];
148 [label="Access variable R|/D.any|"];
149 [label="Variable declaration: lval a: R|kotlin/Any?|"];
150 [label="Access variable R|<local>/a|"];
151 [label="Type operator: a as A"];
152 [label="Access variable R|<local>/a|"];
153 [label="Function call: R|<local>/a|.R|/A.foo|()"];
154 [label="Access variable R|<local>/d1|"];
155 [label="Access variable R|/D.any|"];
156 [label="Function call: R|<local>/d1|.R|/D.any|.R|/A.foo|()"];
157 [label="Access variable R|<local>/d1|"];
158 [label="Access variable R|/D.any|"];
159 [label="Function call: R|<local>/d1|.R|/D.any|.R|/baz|()"];
160 [label="Exit function test_6" style="filled" fillcolor=red];
}
146 -> {147};
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};
subgraph cluster_32 {
color=red
161 [label="Enter function test_7" style="filled" fillcolor=red];
162 [label="Access variable R|<local>/d1|"];
163 [label="Enter safe call"];
164 [label="Access variable R|/D.any|"];
165 [label="Exit safe call"];
166 [label="Variable declaration: lval a: R|kotlin/Any?|"];
167 [label="Access variable R|<local>/d2|"];
168 [label="Enter safe call"];
169 [label="Access variable R|/D.any|"];
170 [label="Exit safe call"];
171 [label="Variable declaration: lval b: R|kotlin/Any?|"];
172 [label="Access variable R|<local>/a|"];
173 [label="Type operator: a as A"];
174 [label="Access variable R|<local>/a|"];
175 [label="Function call: R|<local>/a|.R|/A.foo|()"];
176 [label="Access variable R|<local>/b|"];
177 [label="Type operator: b as B"];
178 [label="Access variable R|<local>/b|"];
179 [label="Function call: R|<local>/b|.R|/B.bar|()"];
180 [label="Exit function test_7" style="filled" fillcolor=red];
}
161 -> {162};
162 -> {163 165};
163 -> {164};
164 -> {165};
165 -> {166};
166 -> {167};
167 -> {168 170};
168 -> {169};
169 -> {170};
170 -> {171};
171 -> {172};
172 -> {173};
173 -> {174};
174 -> {175};
175 -> {176};
176 -> {177};
177 -> {178};
178 -> {179};
179 -> {180};
}
@@ -44,4 +44,34 @@ fun test_4(y: Any) {
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
}
@@ -58,3 +58,44 @@ FILE: boundSmartcasts.kt
}
}
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|()
}
@@ -341,4 +341,143 @@ digraph returns_kt {
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: a as? 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/Boolean|>(<L> = runHigherOrder@fun <anonymous>(): R|kotlin/Boolean| {
^ R|<local>/s|.R|kotlin/text/isNotEmpty|()
}
)"];
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="Function call: R|<local>/s|.R|kotlin/text/isNotEmpty|()"];
169 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
166 -> {167};
167 -> {168};
168 -> {169};
}
@@ -47,4 +47,16 @@ fun test_3(x: Any) {
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.isNotEmpty() // Should be OK
}
}
@@ -65,3 +65,26 @@ FILE: returns.kt
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/Boolean|>(<L> = runHigherOrder@fun <anonymous>(): R|kotlin/Boolean| {
^ R|<local>/s|.R|kotlin/text/isNotEmpty|()
}
)
}
@@ -0,0 +1,139 @@
digraph multipleCasts_kt {
graph [splines=ortho nodesep=3]
node [shape=box penwidth=2]
edge [penwidth=2]
subgraph cluster_0 {
color=red
0 [label="Enter function foo" style="filled" fillcolor=red];
1 [label="Exit function foo" style="filled" fillcolor=red];
}
0 -> {1};
subgraph cluster_1 {
color=red
2 [label="Enter function 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: a as 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: b as 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: a is A"];
33 [label="Exit left part of &&"];
34 [label="Enter right part of &&"];
35 [label="Access variable R|<local>/b|"];
36 [label="Type operator: b is 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};
}
@@ -25,34 +25,4 @@ fun test_1() {
a.foo()
b.foo()
}
}
class D(val any: Any?)
fun Any.baz() {}
fun test_2(d: D) {
// Elvis operator is converted into == function call
val a = d.any ?: return
a.baz()
d.any.baz()
a as A
a.foo()
}
fun test_3(d1: D) {
val a = d1.any
a as A
a.foo()
d1.any.foo()
d1.any.baz()
}
fun test_4(d1: D, d2: D) {
val a = d1?.any
val b = d2?.any
a as A
a.foo()
b as B
b.foo() // should be OK
}
}
@@ -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|()
}
}
}
@@ -1,339 +0,0 @@
digraph notBoundSmartcasts_kt {
graph [splines=ortho nodesep=3]
node [shape=box penwidth=2]
edge [penwidth=2]
subgraph cluster_0 {
color=red
0 [label="Enter function foo" style="filled" fillcolor=red];
1 [label="Exit function foo" style="filled" fillcolor=red];
}
0 -> {1};
subgraph cluster_1 {
color=red
2 [label="Enter function 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: a as 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: b as 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: a is A"];
33 [label="Exit left part of &&"];
34 [label="Enter right part of &&"];
35 [label="Access variable R|<local>/b|"];
36 [label="Type operator: b is 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};
subgraph cluster_9 {
color=red
50 [label="Enter function <init>" style="filled" fillcolor=red];
51 [label="Exit function <init>" style="filled" fillcolor=red];
}
50 -> {51};
subgraph cluster_10 {
color=red
52 [label="Enter function getter" style="filled" fillcolor=red];
53 [label="Exit function getter" style="filled" fillcolor=red];
}
52 -> {53};
subgraph cluster_11 {
color=red
54 [label="Enter property" style="filled" fillcolor=red];
55 [label="Access variable R|<local>/any|"];
56 [label="Exit property" style="filled" fillcolor=red];
}
54 -> {55};
55 -> {56};
subgraph cluster_12 {
color=red
57 [label="Enter function baz" style="filled" fillcolor=red];
58 [label="Exit function baz" style="filled" fillcolor=red];
}
57 -> {58};
subgraph cluster_13 {
color=red
59 [label="Enter function test_2" style="filled" fillcolor=red];
subgraph cluster_14 {
color=blue
60 [label="Enter when"];
61 [label="Access variable R|<local>/d|"];
62 [label="Access variable R|/D.any|"];
63 [label="Variable declaration: lval <elvis>: R|kotlin/Any?|"];
subgraph cluster_15 {
color=blue
64 [label="Enter when branch condition "];
65 [label="Const: Null(null)"];
66 [label="Operator =="];
67 [label="Exit when branch condition"];
}
subgraph cluster_16 {
color=blue
68 [label="Enter when branch condition else"];
69 [label="Exit when branch condition"];
}
70 [label="Enter when branch result"];
subgraph cluster_17 {
color=blue
71 [label="Enter block"];
72 [label="Access variable R|<local>/<elvis>|"];
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="Jump: ^test_2 Unit"];
78 [label="Stub" style="filled" fillcolor=gray];
79 [label="Exit block" style="filled" fillcolor=gray];
}
80 [label="Exit when branch result" style="filled" fillcolor=gray];
81 [label="Exit when"];
}
82 [label="Variable declaration: lval a: R|kotlin/Any|"];
83 [label="Access variable R|<local>/a|"];
84 [label="Function call: R|<local>/a|.R|/baz|()"];
85 [label="Access variable R|<local>/d|"];
86 [label="Access variable R|/D.any|"];
87 [label="Function call: R|<local>/d|.R|/D.any|.R|/baz|()"];
88 [label="Access variable R|<local>/a|"];
89 [label="Type operator: a as A"];
90 [label="Access variable R|<local>/a|"];
91 [label="Function call: R|<local>/a|.R|/A.foo|()"];
92 [label="Exit function test_2" style="filled" fillcolor=red];
}
59 -> {60};
60 -> {61};
61 -> {62};
62 -> {63};
63 -> {64};
64 -> {65};
65 -> {66};
66 -> {67};
67 -> {75 68};
68 -> {69};
69 -> {70};
70 -> {71};
71 -> {72};
72 -> {73};
73 -> {74};
74 -> {81};
75 -> {76};
76 -> {77};
77 -> {92};
77 -> {78} [style=dotted];
78 -> {79} [style=dotted];
79 -> {80} [style=dotted];
80 -> {81} [style=dotted];
81 -> {82};
82 -> {83};
83 -> {84};
84 -> {85};
85 -> {86};
86 -> {87};
87 -> {88};
88 -> {89};
89 -> {90};
90 -> {91};
91 -> {92};
subgraph cluster_19 {
color=red
93 [label="Enter function test_3" style="filled" fillcolor=red];
94 [label="Access variable R|<local>/d1|"];
95 [label="Access variable R|/D.any|"];
96 [label="Variable declaration: lval a: R|kotlin/Any?|"];
97 [label="Access variable R|<local>/a|"];
98 [label="Type operator: a as A"];
99 [label="Access variable R|<local>/a|"];
100 [label="Function call: R|<local>/a|.R|/A.foo|()"];
101 [label="Access variable R|<local>/d1|"];
102 [label="Access variable R|/D.any|"];
103 [label="Function call: R|<local>/d1|.R|/D.any|.R|/A.foo|()"];
104 [label="Access variable R|<local>/d1|"];
105 [label="Access variable R|/D.any|"];
106 [label="Function call: R|<local>/d1|.R|/D.any|.R|/baz|()"];
107 [label="Exit function test_3" style="filled" fillcolor=red];
}
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 -> {107};
subgraph cluster_20 {
color=red
108 [label="Enter function test_4" style="filled" fillcolor=red];
109 [label="Access variable R|<local>/d1|"];
110 [label="Enter safe call"];
111 [label="Access variable R|/D.any|"];
112 [label="Exit safe call"];
113 [label="Variable declaration: lval a: R|kotlin/Any?|"];
114 [label="Access variable R|<local>/d2|"];
115 [label="Enter safe call"];
116 [label="Access variable R|/D.any|"];
117 [label="Exit safe call"];
118 [label="Variable declaration: lval b: R|kotlin/Any?|"];
119 [label="Access variable R|<local>/a|"];
120 [label="Type operator: a as A"];
121 [label="Access variable R|<local>/a|"];
122 [label="Function call: R|<local>/a|.R|/A.foo|()"];
123 [label="Access variable R|<local>/b|"];
124 [label="Type operator: b as B"];
125 [label="Access variable R|<local>/b|"];
126 [label="Function call: R|<local>/b|.R|/B.foo|()"];
127 [label="Exit function test_4" style="filled" fillcolor=red];
}
108 -> {109};
109 -> {110 112};
110 -> {111};
111 -> {112};
112 -> {113};
113 -> {114};
114 -> {115 117};
115 -> {116};
116 -> {117};
117 -> {118};
118 -> {119};
119 -> {120};
120 -> {121};
121 -> {122};
122 -> {123};
123 -> {124};
124 -> {125};
125 -> {126};
126 -> {127};
}
@@ -1,72 +0,0 @@
FILE: notBoundSmartcasts.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|()
}
}
}
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_2(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_2 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_3(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_4(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.foo|()
}
@@ -0,0 +1,59 @@
digraph smartcastOnBangBang_kt {
graph [splines=ortho nodesep=3]
node [shape=box penwidth=2]
edge [penwidth=2]
subgraph cluster_0 {
color=red
0 [label="Enter function test_1" style="filled" fillcolor=red];
subgraph cluster_1 {
color=blue
1 [label="Enter when"];
subgraph cluster_2 {
color=blue
2 [label="Enter when branch condition "];
3 [label="Access variable R|<local>/a|"];
4 [label="Type operator: a is 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>/a|"];
10 [label="Check not null: R|<local>/a|!!"];
11 [label="Function call: <Inapplicable(INAPPLICABLE): [/takeString]>#(R|<local>/a|!!)"];
12 [label="Exit block"];
}
13 [label="Exit when branch result"];
14 [label="Exit when"];
}
15 [label="Exit function test_1" style="filled" fillcolor=red];
}
0 -> {1};
1 -> {2};
2 -> {3};
3 -> {4};
4 -> {5};
5 -> {7 6};
6 -> {14};
7 -> {8};
8 -> {9};
9 -> {10};
10 -> {11};
11 -> {12};
12 -> {13};
13 -> {14};
14 -> {15};
subgraph cluster_4 {
color=red
16 [label="Enter function takeString" style="filled" fillcolor=red];
17 [label="Exit function takeString" style="filled" fillcolor=red];
}
16 -> {17};
}
@@ -0,0 +1,7 @@
fun <X> test_1(a: X) {
if (a is String?) {
<!INAPPLICABLE_CANDIDATE!>takeString<!>(a!!)
}
}
fun takeString(s: String) {}
@@ -0,0 +1,11 @@
FILE: smartcastOnBangBang.kt
public final fun <X> test_1(a: R|X|): R|kotlin/Unit| {
when () {
(R|<local>/a| is R|kotlin/String?|) -> {
<Inapplicable(INAPPLICABLE): [/takeString]>#(R|<local>/a|!!)
}
}
}
public final fun takeString(s: R|kotlin/String|): R|kotlin/Unit| {
}
@@ -1,4 +1,4 @@
digraph anotherBoundSmartcasts_kt {
digraph assignSafeCall_kt {
graph [splines=ortho nodesep=3]
node [shape=box penwidth=2]
edge [penwidth=2]
@@ -1,4 +1,4 @@
FILE: anotherBoundSmartcasts.kt
FILE: assignSafeCall.kt
public final class A : R|kotlin/Any| {
public constructor(): R|A| {
super<R|kotlin/Any|>()
@@ -0,0 +1,290 @@
digraph safeCallAndEqualityToBool_kt {
graph [splines=ortho nodesep=3]
node [shape=box penwidth=2]
edge [penwidth=2]
subgraph cluster_0 {
color=red
0 [label="Enter function test_1" style="filled" fillcolor=red];
subgraph cluster_1 {
color=blue
1 [label="Enter when"];
subgraph cluster_2 {
color=blue
2 [label="Enter when branch condition "];
3 [label="Access variable R|<local>/s|"];
4 [label="Enter safe call"];
5 [label="Function call: R|<local>/s|?.R|kotlin/text/isNotEmpty|()"];
6 [label="Exit safe call"];
7 [label="Const: Boolean(true)"];
8 [label="Operator =="];
9 [label="Exit when branch condition"];
}
subgraph cluster_3 {
color=blue
10 [label="Enter when branch condition else"];
11 [label="Exit when branch condition"];
}
12 [label="Enter when branch result"];
subgraph cluster_4 {
color=blue
13 [label="Enter block"];
14 [label="Access variable R|<local>/s|"];
15 [label="Access variable <Inapplicable(WRONG_RECEIVER): [kotlin/String.length]>#"];
16 [label="Exit block"];
}
17 [label="Exit when branch result"];
18 [label="Enter when branch result"];
subgraph cluster_5 {
color=blue
19 [label="Enter block"];
20 [label="Access variable R|<local>/s|"];
21 [label="Access variable R|kotlin/String.length|"];
22 [label="Exit block"];
}
23 [label="Exit when branch result"];
24 [label="Exit when"];
}
25 [label="Exit function test_1" style="filled" fillcolor=red];
}
0 -> {1};
1 -> {2};
2 -> {3};
3 -> {4 6};
4 -> {5};
5 -> {6};
6 -> {7};
7 -> {8};
8 -> {9};
9 -> {18 10};
10 -> {11};
11 -> {12};
12 -> {13};
13 -> {14};
14 -> {15};
15 -> {16};
16 -> {17};
17 -> {24};
18 -> {19};
19 -> {20};
20 -> {21};
21 -> {22};
22 -> {23};
23 -> {24};
24 -> {25};
subgraph cluster_6 {
color=red
26 [label="Enter function test_2" style="filled" fillcolor=red];
subgraph cluster_7 {
color=blue
27 [label="Enter when"];
subgraph cluster_8 {
color=blue
28 [label="Enter when branch condition "];
29 [label="Access variable R|<local>/s|"];
30 [label="Enter safe call"];
31 [label="Function call: R|<local>/s|?.R|kotlin/text/isNotEmpty|()"];
32 [label="Exit safe call"];
33 [label="Const: Boolean(false)"];
34 [label="Operator =="];
35 [label="Exit when branch condition"];
}
subgraph cluster_9 {
color=blue
36 [label="Enter when branch condition else"];
37 [label="Exit when branch condition"];
}
38 [label="Enter when branch result"];
subgraph cluster_10 {
color=blue
39 [label="Enter block"];
40 [label="Access variable R|<local>/s|"];
41 [label="Access variable <Inapplicable(WRONG_RECEIVER): [kotlin/String.length]>#"];
42 [label="Exit block"];
}
43 [label="Exit when branch result"];
44 [label="Enter when branch result"];
subgraph cluster_11 {
color=blue
45 [label="Enter block"];
46 [label="Access variable R|<local>/s|"];
47 [label="Access variable R|kotlin/String.length|"];
48 [label="Exit block"];
}
49 [label="Exit when branch result"];
50 [label="Exit when"];
}
51 [label="Exit function test_2" style="filled" fillcolor=red];
}
26 -> {27};
27 -> {28};
28 -> {29};
29 -> {30 32};
30 -> {31};
31 -> {32};
32 -> {33};
33 -> {34};
34 -> {35};
35 -> {44 36};
36 -> {37};
37 -> {38};
38 -> {39};
39 -> {40};
40 -> {41};
41 -> {42};
42 -> {43};
43 -> {50};
44 -> {45};
45 -> {46};
46 -> {47};
47 -> {48};
48 -> {49};
49 -> {50};
50 -> {51};
subgraph cluster_12 {
color=red
52 [label="Enter function test_3" style="filled" fillcolor=red];
subgraph cluster_13 {
color=blue
53 [label="Enter when"];
subgraph cluster_14 {
color=blue
54 [label="Enter when branch condition "];
55 [label="Access variable R|<local>/s|"];
56 [label="Enter safe call"];
57 [label="Function call: R|<local>/s|?.R|kotlin/text/isNotEmpty|()"];
58 [label="Exit safe call"];
59 [label="Const: Boolean(true)"];
60 [label="Operator !="];
61 [label="Exit when branch condition"];
}
subgraph cluster_15 {
color=blue
62 [label="Enter when branch condition else"];
63 [label="Exit when branch condition"];
}
64 [label="Enter when branch result"];
subgraph cluster_16 {
color=blue
65 [label="Enter block"];
66 [label="Access variable R|<local>/s|"];
67 [label="Access variable R|kotlin/String.length|"];
68 [label="Exit block"];
}
69 [label="Exit when branch result"];
70 [label="Enter when branch result"];
subgraph cluster_17 {
color=blue
71 [label="Enter block"];
72 [label="Access variable R|<local>/s|"];
73 [label="Access variable <Inapplicable(WRONG_RECEIVER): [kotlin/String.length]>#"];
74 [label="Exit block"];
}
75 [label="Exit when branch result"];
76 [label="Exit when"];
}
77 [label="Exit function test_3" style="filled" fillcolor=red];
}
52 -> {53};
53 -> {54};
54 -> {55};
55 -> {56 58};
56 -> {57};
57 -> {58};
58 -> {59};
59 -> {60};
60 -> {61};
61 -> {70 62};
62 -> {63};
63 -> {64};
64 -> {65};
65 -> {66};
66 -> {67};
67 -> {68};
68 -> {69};
69 -> {76};
70 -> {71};
71 -> {72};
72 -> {73};
73 -> {74};
74 -> {75};
75 -> {76};
76 -> {77};
subgraph cluster_18 {
color=red
78 [label="Enter function test_4" style="filled" fillcolor=red];
subgraph cluster_19 {
color=blue
79 [label="Enter when"];
subgraph cluster_20 {
color=blue
80 [label="Enter when branch condition "];
81 [label="Access variable R|<local>/s|"];
82 [label="Enter safe call"];
83 [label="Function call: R|<local>/s|?.R|kotlin/text/isNotEmpty|()"];
84 [label="Exit safe call"];
85 [label="Const: Boolean(false)"];
86 [label="Operator !="];
87 [label="Exit when branch condition"];
}
subgraph cluster_21 {
color=blue
88 [label="Enter when branch condition else"];
89 [label="Exit when branch condition"];
}
90 [label="Enter when branch result"];
subgraph cluster_22 {
color=blue
91 [label="Enter block"];
92 [label="Access variable R|<local>/s|"];
93 [label="Access variable R|kotlin/String.length|"];
94 [label="Exit block"];
}
95 [label="Exit when branch result"];
96 [label="Enter when branch result"];
subgraph cluster_23 {
color=blue
97 [label="Enter block"];
98 [label="Access variable R|<local>/s|"];
99 [label="Access variable <Inapplicable(WRONG_RECEIVER): [kotlin/String.length]>#"];
100 [label="Exit block"];
}
101 [label="Exit when branch result"];
102 [label="Exit when"];
}
103 [label="Exit function test_4" style="filled" fillcolor=red];
}
78 -> {79};
79 -> {80};
80 -> {81};
81 -> {82 84};
82 -> {83};
83 -> {84};
84 -> {85};
85 -> {86};
86 -> {87};
87 -> {96 88};
88 -> {89};
89 -> {90};
90 -> {91};
91 -> {92};
92 -> {93};
93 -> {94};
94 -> {95};
95 -> {102};
96 -> {97};
97 -> {98};
98 -> {99};
99 -> {100};
100 -> {101};
101 -> {102};
102 -> {103};
}
@@ -0,0 +1,31 @@
fun test_1(s: String?) {
if (s?.isNotEmpty() == true) {
s.length // Should be OK
} else {
s.<!INAPPLICABLE_CANDIDATE!>length<!> // Should be bad
}
}
fun test_2(s: String?) {
if (s?.isNotEmpty() == false) {
s.length // Should be OK
} else {
s.<!INAPPLICABLE_CANDIDATE!>length<!> // Should be bad
}
}
fun test_3(s: String?) {
if (s?.isNotEmpty() != true) {
s.<!INAPPLICABLE_CANDIDATE!>length<!> // Should be bad
} else {
s.length // Should be OK
}
}
fun test_4(s: String?) {
if (s?.isNotEmpty() != false) {
s.<!INAPPLICABLE_CANDIDATE!>length<!> // Should be bad
} else {
s.length // Should be OK
}
}
@@ -0,0 +1,45 @@
FILE: safeCallAndEqualityToBool.kt
public final fun test_1(s: R|kotlin/String?|): R|kotlin/Unit| {
when () {
==(R|<local>/s|?.R|kotlin/text/isNotEmpty|(), 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|kotlin/text/isNotEmpty|(), 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|kotlin/text/isNotEmpty|(), 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|kotlin/text/isNotEmpty|(), Boolean(false)) -> {
R|<local>/s|.<Inapplicable(WRONG_RECEIVER): [kotlin/String.length]>#
}
else -> {
R|<local>/s|.R|kotlin/String.length|
}
}
}
@@ -1,71 +1,31 @@
fun <T> runHigherOrder(f: () -> T): T = f()
val String.ext: Int get() = length
fun foo(a: Any?) {
val s = a as? String
val length = s?.ext ?: return
runHigherOrder {
s.isNotEmpty()
}
}
fun bar(s: String?) {
if (s?.isNotEmpty() == true) {
s.length
} else {
s.<!INAPPLICABLE_CANDIDATE!>length<!>
}
}
fun bar_2(s: String?) {
if (s?.isNotEmpty() == false) {
s.length
} else {
s.<!INAPPLICABLE_CANDIDATE!>length<!>
}
}
fun bar_3(s: String?) {
if (s?.isNotEmpty() != true) {
s.<!INAPPLICABLE_CANDIDATE!>length<!>
} else {
s.length
}
}
fun bar_4(s: String?) {
if (s?.isNotEmpty() != false) {
s.<!INAPPLICABLE_CANDIDATE!>length<!>
} else {
s.length
}
}
fun baz(s: String?) {
fun test_1(s: String?) {
// contracts related
when {
!s.isNullOrEmpty() -> s.<!INAPPLICABLE_CANDIDATE!>length<!>
!s.isNullOrEmpty() -> s.<!INAPPLICABLE_CANDIDATE!>length<!> // Should be OK
}
}
fun bazz(s: String?) {
s?.let { use(it) }
fun test_2(s: String?) {
s?.let {
takeString(it) // Should be OK
takeString(s) // Should be OK
}
}
class Wrapper(val s: String?) {
fun withThis() {
if (s != null) {
use(this.s)
takeString(this.s) // Should be OK
}
if (this.s != null) {
use(s)
takeString(s) // Should be OK
}
}
}
fun Any.withInvoke(f: String.() -> Unit) {
if (this is String) {
<!INAPPLICABLE_CANDIDATE!>f<!>()
<!INAPPLICABLE_CANDIDATE!>f<!>() // Should be OK
}
}
@@ -73,11 +33,5 @@ fun String.withInvoke(f: String.() -> Unit) {
f()
}
fun <X> withBangBang(a: X) {
if (a is String?) {
<!INAPPLICABLE_CANDIDATE!>use<!>(a!!)
}
}
fun use(s: String) {}
fun takeString(s: String) {}
@@ -1,72 +1,5 @@
FILE: complexSmartCasts.kt
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 foo(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)) -> {
^foo Unit
}
else -> {
R|<local>/<elvis>|
}
}
R|/runHigherOrder|<R|kotlin/Boolean|>(<L> = runHigherOrder@fun <anonymous>(): R|kotlin/Boolean| {
^ R|<local>/s|.R|kotlin/text/isNotEmpty|()
}
)
}
public final fun bar(s: R|kotlin/String?|): R|kotlin/Unit| {
when () {
==(R|<local>/s|?.R|kotlin/text/isNotEmpty|(), Boolean(true)) -> {
R|<local>/s|.R|kotlin/String.length|
}
else -> {
R|<local>/s|.<Inapplicable(WRONG_RECEIVER): [kotlin/String.length]>#
}
}
}
public final fun bar_2(s: R|kotlin/String?|): R|kotlin/Unit| {
when () {
==(R|<local>/s|?.R|kotlin/text/isNotEmpty|(), Boolean(false)) -> {
R|<local>/s|.R|kotlin/String.length|
}
else -> {
R|<local>/s|.<Inapplicable(WRONG_RECEIVER): [kotlin/String.length]>#
}
}
}
public final fun bar_3(s: R|kotlin/String?|): R|kotlin/Unit| {
when () {
!=(R|<local>/s|?.R|kotlin/text/isNotEmpty|(), Boolean(true)) -> {
R|<local>/s|.<Inapplicable(WRONG_RECEIVER): [kotlin/String.length]>#
}
else -> {
R|<local>/s|.R|kotlin/String.length|
}
}
}
public final fun bar_4(s: R|kotlin/String?|): R|kotlin/Unit| {
when () {
!=(R|<local>/s|?.R|kotlin/text/isNotEmpty|(), Boolean(false)) -> {
R|<local>/s|.<Inapplicable(WRONG_RECEIVER): [kotlin/String.length]>#
}
else -> {
R|<local>/s|.R|kotlin/String.length|
}
}
}
public final fun baz(s: R|kotlin/String?|): R|kotlin/Unit| {
public final fun test_1(s: R|kotlin/String?|): R|kotlin/Unit| {
when () {
R|<local>/s|.R|kotlin/text/isNullOrEmpty|().R|kotlin/Boolean.not|() -> {
R|<local>/s|.<Inapplicable(WRONG_RECEIVER): [kotlin/String.length]>#
@@ -74,9 +7,10 @@ FILE: complexSmartCasts.kt
}
}
public final fun bazz(s: R|kotlin/String?|): R|kotlin/Unit| {
public final fun test_2(s: R|kotlin/String?|): R|kotlin/Unit| {
R|<local>/s|?.R|kotlin/let|<R|kotlin/String|, R|kotlin/Unit|>(<L> = let@fun <anonymous>(it: R|kotlin/String|): R|kotlin/Unit| <kind=EXACTLY_ONCE> {
R|/use|(R|<local>/it|)
R|/takeString|(R|<local>/it|)
R|/takeString|(R|<local>/s|)
}
)
}
@@ -91,13 +25,13 @@ FILE: complexSmartCasts.kt
public final fun withThis(): R|kotlin/Unit| {
when () {
!=(this@R|/Wrapper|.R|/Wrapper.s|, Null(null)) -> {
R|/use|(this@R|/Wrapper|.R|/Wrapper.s|)
R|/takeString|(this@R|/Wrapper|.R|/Wrapper.s|)
}
}
when () {
!=(this@R|/Wrapper|.R|/Wrapper.s|, Null(null)) -> {
R|/use|(this@R|/Wrapper|.R|/Wrapper.s|)
R|/takeString|(this@R|/Wrapper|.R|/Wrapper.s|)
}
}
@@ -115,13 +49,5 @@ FILE: complexSmartCasts.kt
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|)
}
public final fun <X> withBangBang(a: R|X|): R|kotlin/Unit| {
when () {
(R|<local>/a| is R|kotlin/String?|) -> {
<Inapplicable(INAPPLICABLE): [/use]>#(R|<local>/a|!!)
}
}
}
public final fun use(s: R|kotlin/String|): R|kotlin/Unit| {
public final fun takeString(s: R|kotlin/String|): R|kotlin/Unit| {
}
@@ -123,84 +123,24 @@ public class FirDiagnosticsWithCfgTestGenerated extends AbstractFirDiagnosticsWi
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/resolve/testData/resolve/smartcasts"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@TestMetadata("anotherBoundSmartcasts.kt")
public void testAnotherBoundSmartcasts() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/anotherBoundSmartcasts.kt");
}
@TestMetadata("bangbang.kt")
public void testBangbang() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/bangbang.kt");
}
@TestMetadata("booleanOperators.kt")
public void testBooleanOperators() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/booleanOperators.kt");
}
@TestMetadata("boundSmartcasts.kt")
public void testBoundSmartcasts() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/boundSmartcasts.kt");
}
@TestMetadata("boundSmartcastsInBranches.kt")
public void testBoundSmartcastsInBranches() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/boundSmartcastsInBranches.kt");
}
@TestMetadata("casts.kt")
public void testCasts() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/casts.kt");
}
@TestMetadata("dataFlowInfoFromWhileCondition.kt")
public void testDataFlowInfoFromWhileCondition() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/dataFlowInfoFromWhileCondition.kt");
}
@TestMetadata("delayedAssignment.kt")
public void testDelayedAssignment() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/delayedAssignment.kt");
}
@TestMetadata("elvis.kt")
public void testElvis() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/elvis.kt");
}
@TestMetadata("endlessLoops.kt")
public void testEndlessLoops() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/endlessLoops.kt");
}
@TestMetadata("equalsAndIdentity.kt")
public void testEqualsAndIdentity() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/equalsAndIdentity.kt");
}
@TestMetadata("equalsToBoolean.kt")
public void testEqualsToBoolean() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/equalsToBoolean.kt");
}
@TestMetadata("implicitReceiverAsWhenSubject.kt")
public void testImplicitReceiverAsWhenSubject() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/implicitReceiverAsWhenSubject.kt");
}
@TestMetadata("implicitReceivers.kt")
public void testImplicitReceivers() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/implicitReceivers.kt");
}
@TestMetadata("inPlaceLambdas.kt")
public void testInPlaceLambdas() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/inPlaceLambdas.kt");
}
@TestMetadata("notBoundSmartcasts.kt")
public void testNotBoundSmartcasts() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/notBoundSmartcasts.kt");
@TestMetadata("multipleCasts.kt")
public void testMultipleCasts() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/multipleCasts.kt");
}
@TestMetadata("nullability.kt")
@@ -208,59 +148,259 @@ public class FirDiagnosticsWithCfgTestGenerated extends AbstractFirDiagnosticsWi
runTest("compiler/fir/resolve/testData/resolve/smartcasts/nullability.kt");
}
@TestMetadata("overridenOpenVal.kt")
public void testOverridenOpenVal() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/overridenOpenVal.kt");
}
@TestMetadata("returns.kt")
public void testReturns() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/returns.kt");
}
@TestMetadata("safeCalls.kt")
public void testSafeCalls() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/safeCalls.kt");
}
@TestMetadata("simpleIf.kt")
public void testSimpleIf() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/simpleIf.kt");
}
@TestMetadata("smartCastInInit.kt")
public void testSmartCastInInit() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/smartCastInInit.kt");
}
@TestMetadata("smartcastAfterReassignment.kt")
public void testSmartcastAfterReassignment() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/smartcastAfterReassignment.kt");
}
@TestMetadata("smartcastFromArgument.kt")
public void testSmartcastFromArgument() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/smartcastFromArgument.kt");
}
@TestMetadata("smartcastOnLambda.kt")
public void testSmartcastOnLambda() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/smartcastOnLambda.kt");
}
@TestMetadata("smartcastToNothing.kt")
public void testSmartcastToNothing() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/smartcastToNothing.kt");
}
@TestMetadata("thisOfExtensionProperty.kt")
public void testThisOfExtensionProperty() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/thisOfExtensionProperty.kt");
@TestMetadata("compiler/fir/resolve/testData/resolve/smartcasts/booleans")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Booleans extends AbstractFirDiagnosticsWithCfgTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
public void testAllFilesPresentInBooleans() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/resolve/testData/resolve/smartcasts/booleans"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@TestMetadata("booleanOperators.kt")
public void testBooleanOperators() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/booleans/booleanOperators.kt");
}
@TestMetadata("equalsToBoolean.kt")
public void testEqualsToBoolean() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/booleans/equalsToBoolean.kt");
}
}
@TestMetadata("when.kt")
public void testWhen() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/when.kt");
@TestMetadata("compiler/fir/resolve/testData/resolve/smartcasts/boundSmartcasts")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class BoundSmartcasts extends AbstractFirDiagnosticsWithCfgTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
public void testAllFilesPresentInBoundSmartcasts() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/resolve/testData/resolve/smartcasts/boundSmartcasts"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@TestMetadata("boundSmartcasts.kt")
public void testBoundSmartcasts() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/boundSmartcasts/boundSmartcasts.kt");
}
@TestMetadata("boundSmartcastsInBranches.kt")
public void testBoundSmartcastsInBranches() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/boundSmartcasts/boundSmartcastsInBranches.kt");
}
}
@TestMetadata("compiler/fir/resolve/testData/resolve/smartcasts/controlStructures")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class ControlStructures extends AbstractFirDiagnosticsWithCfgTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
public void testAllFilesPresentInControlStructures() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/resolve/testData/resolve/smartcasts/controlStructures"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@TestMetadata("elvis.kt")
public void testElvis() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/controlStructures/elvis.kt");
}
@TestMetadata("returns.kt")
public void testReturns() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/controlStructures/returns.kt");
}
@TestMetadata("simpleIf.kt")
public void testSimpleIf() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/controlStructures/simpleIf.kt");
}
@TestMetadata("smartcastFromArgument.kt")
public void testSmartcastFromArgument() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/controlStructures/smartcastFromArgument.kt");
}
@TestMetadata("when.kt")
public void testWhen() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/controlStructures/when.kt");
}
}
@TestMetadata("compiler/fir/resolve/testData/resolve/smartcasts/lambdas")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Lambdas extends AbstractFirDiagnosticsWithCfgTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
public void testAllFilesPresentInLambdas() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/resolve/testData/resolve/smartcasts/lambdas"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@TestMetadata("inPlaceLambdas.kt")
public void testInPlaceLambdas() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/lambdas/inPlaceLambdas.kt");
}
@TestMetadata("smartcastOnLambda.kt")
public void testSmartcastOnLambda() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/lambdas/smartcastOnLambda.kt");
}
}
@TestMetadata("compiler/fir/resolve/testData/resolve/smartcasts/loops")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Loops extends AbstractFirDiagnosticsWithCfgTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
public void testAllFilesPresentInLoops() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/resolve/testData/resolve/smartcasts/loops"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@TestMetadata("dataFlowInfoFromWhileCondition.kt")
public void testDataFlowInfoFromWhileCondition() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/loops/dataFlowInfoFromWhileCondition.kt");
}
@TestMetadata("endlessLoops.kt")
public void testEndlessLoops() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/loops/endlessLoops.kt");
}
}
@TestMetadata("compiler/fir/resolve/testData/resolve/smartcasts/problems")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Problems extends AbstractFirDiagnosticsWithCfgTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
public void testAllFilesPresentInProblems() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/resolve/testData/resolve/smartcasts/problems"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@TestMetadata("smartcastOnBangBang.kt")
public void testSmartcastOnBangBang() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/problems/smartcastOnBangBang.kt");
}
}
@TestMetadata("compiler/fir/resolve/testData/resolve/smartcasts/receivers")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Receivers extends AbstractFirDiagnosticsWithCfgTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
public void testAllFilesPresentInReceivers() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/resolve/testData/resolve/smartcasts/receivers"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@TestMetadata("implicitReceiverAsWhenSubject.kt")
public void testImplicitReceiverAsWhenSubject() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/receivers/implicitReceiverAsWhenSubject.kt");
}
@TestMetadata("implicitReceivers.kt")
public void testImplicitReceivers() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/receivers/implicitReceivers.kt");
}
@TestMetadata("thisOfExtensionProperty.kt")
public void testThisOfExtensionProperty() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/receivers/thisOfExtensionProperty.kt");
}
}
@TestMetadata("compiler/fir/resolve/testData/resolve/smartcasts/safeCalls")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class SafeCalls extends AbstractFirDiagnosticsWithCfgTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
public void testAllFilesPresentInSafeCalls() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/resolve/testData/resolve/smartcasts/safeCalls"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@TestMetadata("assignSafeCall.kt")
public void testAssignSafeCall() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/safeCalls/assignSafeCall.kt");
}
@TestMetadata("safeCallAndEqualityToBool.kt")
public void testSafeCallAndEqualityToBool() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/safeCalls/safeCallAndEqualityToBool.kt");
}
@TestMetadata("safeCalls.kt")
public void testSafeCalls() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/safeCalls/safeCalls.kt");
}
}
@TestMetadata("compiler/fir/resolve/testData/resolve/smartcasts/stability")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Stability extends AbstractFirDiagnosticsWithCfgTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
public void testAllFilesPresentInStability() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/resolve/testData/resolve/smartcasts/stability"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@TestMetadata("overridenOpenVal.kt")
public void testOverridenOpenVal() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/stability/overridenOpenVal.kt");
}
}
@TestMetadata("compiler/fir/resolve/testData/resolve/smartcasts/variables")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Variables extends AbstractFirDiagnosticsWithCfgTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
public void testAllFilesPresentInVariables() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/resolve/testData/resolve/smartcasts/variables"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@TestMetadata("delayedAssignment.kt")
public void testDelayedAssignment() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/variables/delayedAssignment.kt");
}
@TestMetadata("smartcastAfterReassignment.kt")
public void testSmartcastAfterReassignment() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/smartcasts/variables/smartcastAfterReassignment.kt");
}
}
}
}