[FIR] Implement checker for exhaustive when's in expression position
This commit is contained in:
Vendored
+55
@@ -0,0 +1,55 @@
|
||||
FILE: missingBooleanBranch.kt
|
||||
public final fun test_1(cond: R|kotlin/Boolean|): R|kotlin/Unit| {
|
||||
lval x: R|kotlin/Unit| = when (R|<local>/cond|) {
|
||||
==($subj$, Boolean(true)) -> {
|
||||
Int(1)
|
||||
}
|
||||
}
|
||||
|
||||
lval y: R|kotlin/Unit| = when (R|<local>/cond|) {
|
||||
==($subj$, Boolean(false)) -> {
|
||||
Int(2)
|
||||
}
|
||||
}
|
||||
|
||||
lval z: R|kotlin/Int| = when (R|<local>/cond|) {
|
||||
==($subj$, Boolean(true)) -> {
|
||||
Int(1)
|
||||
}
|
||||
==($subj$, Boolean(false)) -> {
|
||||
Int(2)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public final fun test_2(cond: R|kotlin/Boolean?|): R|kotlin/Unit| {
|
||||
lval x: R|kotlin/Unit| = when (R|<local>/cond|) {
|
||||
==($subj$, Boolean(true)) -> {
|
||||
Int(1)
|
||||
}
|
||||
==($subj$, Boolean(false)) -> {
|
||||
Int(2)
|
||||
}
|
||||
}
|
||||
|
||||
lval x: R|kotlin/Int| = when (R|<local>/cond|) {
|
||||
==($subj$, Boolean(true)) -> {
|
||||
Int(1)
|
||||
}
|
||||
==($subj$, Boolean(false)) -> {
|
||||
Int(2)
|
||||
}
|
||||
==($subj$, Null(null)) -> {
|
||||
Int(3)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public final fun test_3(cond: R|kotlin/Boolean|): R|kotlin/Unit| {
|
||||
when (R|<local>/cond|) {
|
||||
==($subj$, Boolean(true)) -> {
|
||||
Int(1)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Vendored
+33
@@ -0,0 +1,33 @@
|
||||
fun test_1(cond: Boolean) {
|
||||
val x = <!NO_ELSE_IN_WHEN!>when<!> (cond) {
|
||||
true -> 1
|
||||
}
|
||||
|
||||
val y = <!NO_ELSE_IN_WHEN!>when<!> (cond) {
|
||||
false -> 2
|
||||
}
|
||||
|
||||
val z = when (cond) {
|
||||
true -> 1
|
||||
false -> 2
|
||||
}
|
||||
}
|
||||
|
||||
fun test_2(cond: Boolean?) {
|
||||
val x = <!NO_ELSE_IN_WHEN!>when<!> (cond) {
|
||||
true -> 1
|
||||
false -> 2
|
||||
}
|
||||
|
||||
val x = when (cond) {
|
||||
true -> 1
|
||||
false -> 2
|
||||
null -> 3
|
||||
}
|
||||
}
|
||||
|
||||
fun test_3(cond: Boolean) {
|
||||
when (cond) {
|
||||
true -> 1
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
FILE: missingElse.kt
|
||||
public final fun test(a: R|kotlin/Any|): R|kotlin/Unit| {
|
||||
lval x: R|kotlin/Unit| = when (R|<local>/a|) {
|
||||
($subj$ is R|kotlin/Int|) -> {
|
||||
Int(1)
|
||||
}
|
||||
($subj$ is R|kotlin/String|) -> {
|
||||
Int(2)
|
||||
}
|
||||
}
|
||||
|
||||
lval y: R|kotlin/Int| = when (R|<local>/a|) {
|
||||
else -> {
|
||||
Int(1)
|
||||
}
|
||||
}
|
||||
|
||||
lval z: R|kotlin/Int| = when (R|<local>/a|) {
|
||||
($subj$ is R|kotlin/Int|) -> {
|
||||
Int(1)
|
||||
}
|
||||
($subj$ is R|kotlin/String|) -> {
|
||||
Int(2)
|
||||
}
|
||||
else -> {
|
||||
Int(3)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public final fun test_2(a: R|kotlin/Any|): R|kotlin/Unit| {
|
||||
when (R|<local>/a|) {
|
||||
($subj$ is R|kotlin/String|) -> {
|
||||
Int(1)
|
||||
}
|
||||
($subj$ is R|kotlin/Int|) -> {
|
||||
Int(2)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
fun test(a: Any) {
|
||||
val x = <!NO_ELSE_IN_WHEN!>when<!> (a) {
|
||||
is Int -> 1
|
||||
is String -> 2
|
||||
}
|
||||
|
||||
val y = when (a) {
|
||||
else -> 1
|
||||
}
|
||||
|
||||
val z = when (a) {
|
||||
is Int -> 1
|
||||
is String -> 2
|
||||
else -> 3
|
||||
}
|
||||
}
|
||||
|
||||
fun test_2(a: Any) {
|
||||
when (a) {
|
||||
is String -> 1
|
||||
is Int -> 2
|
||||
}
|
||||
}
|
||||
Vendored
+63
@@ -0,0 +1,63 @@
|
||||
FILE: missingEnumEntry.kt
|
||||
public final enum class SomeEnum : R|kotlin/Enum<SomeEnum>| {
|
||||
private constructor(): R|SomeEnum| {
|
||||
super<R|kotlin/Enum<SomeEnum>|>()
|
||||
}
|
||||
|
||||
public final static enum entry A: R|SomeEnum|
|
||||
public final static enum entry B: R|SomeEnum|
|
||||
public final static fun values(): R|kotlin/Array<SomeEnum>| {
|
||||
}
|
||||
|
||||
public final static fun valueOf(value: R|kotlin/String|): R|SomeEnum| {
|
||||
}
|
||||
|
||||
}
|
||||
public final fun test_1(enum: R|SomeEnum|): R|kotlin/Unit| {
|
||||
lval x: R|kotlin/Unit| = when (R|<local>/enum|) {
|
||||
==($subj$, Q|SomeEnum|.R|/SomeEnum.A|) -> {
|
||||
Int(1)
|
||||
}
|
||||
}
|
||||
|
||||
lval y: R|kotlin/Int| = when (R|<local>/enum|) {
|
||||
==($subj$, Q|SomeEnum|.R|/SomeEnum.A|) -> {
|
||||
Int(1)
|
||||
}
|
||||
==($subj$, Q|SomeEnum|.R|/SomeEnum.B|) -> {
|
||||
Int(2)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public final fun test_2(enum: R|SomeEnum?|): R|kotlin/Unit| {
|
||||
lval x: R|kotlin/Unit| = when (R|<local>/enum|) {
|
||||
==($subj$, Q|SomeEnum|.R|/SomeEnum.A|) -> {
|
||||
Int(1)
|
||||
}
|
||||
==($subj$, Q|SomeEnum|.R|/SomeEnum.B|) -> {
|
||||
Int(2)
|
||||
}
|
||||
}
|
||||
|
||||
lval y: R|kotlin/Int| = when (R|<local>/enum|) {
|
||||
==($subj$, Q|SomeEnum|.R|/SomeEnum.A|) -> {
|
||||
Int(1)
|
||||
}
|
||||
==($subj$, Q|SomeEnum|.R|/SomeEnum.B|) -> {
|
||||
Int(2)
|
||||
}
|
||||
==($subj$, Null(null)) -> {
|
||||
Int(3)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public final fun test_3(enum: R|SomeEnum|): R|kotlin/Unit| {
|
||||
when (R|<local>/enum|) {
|
||||
==($subj$, Q|SomeEnum|.R|/SomeEnum.A|) -> {
|
||||
Int(1)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
enum class SomeEnum {
|
||||
A, B
|
||||
}
|
||||
|
||||
fun test_1(enum: SomeEnum) {
|
||||
val x = <!NO_ELSE_IN_WHEN!>when<!> (enum) {
|
||||
SomeEnum.A -> 1
|
||||
}
|
||||
|
||||
val y = when (enum) {
|
||||
SomeEnum.A -> 1
|
||||
SomeEnum.B -> 2
|
||||
}
|
||||
}
|
||||
|
||||
fun test_2(enum: SomeEnum?) {
|
||||
val x = <!NO_ELSE_IN_WHEN!>when<!> (enum) {
|
||||
SomeEnum.A -> 1
|
||||
SomeEnum.B -> 2
|
||||
}
|
||||
|
||||
val y = when (enum) {
|
||||
SomeEnum.A -> 1
|
||||
SomeEnum.B -> 2
|
||||
null -> 3
|
||||
}
|
||||
}
|
||||
|
||||
fun test_3(enum: SomeEnum) {
|
||||
when (enum) {
|
||||
SomeEnum.A -> 1
|
||||
}
|
||||
}
|
||||
Vendored
+84
@@ -0,0 +1,84 @@
|
||||
FILE: a.kt
|
||||
public sealed class Base : R|kotlin/Any| {
|
||||
private constructor(): R|Base| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
public final class A : R|Base| {
|
||||
public constructor(): R|A| {
|
||||
super<R|Base|>()
|
||||
}
|
||||
|
||||
}
|
||||
FILE: b.kt
|
||||
public final object B : R|Base| {
|
||||
private constructor(): R|B| {
|
||||
super<R|Base|>()
|
||||
}
|
||||
|
||||
}
|
||||
FILE: c.kt
|
||||
public final fun test_1(base: R|Base|): R|kotlin/Unit| {
|
||||
lval x: R|kotlin/Unit| = when (R|<local>/base|) {
|
||||
($subj$ is R|A|) -> {
|
||||
Int(1)
|
||||
}
|
||||
}
|
||||
|
||||
lval y: R|kotlin/Unit| = when (R|<local>/base|) {
|
||||
==($subj$, Q|B|) -> {
|
||||
Int(1)
|
||||
}
|
||||
}
|
||||
|
||||
lval z: R|kotlin/Int| = when (R|<local>/base|) {
|
||||
($subj$ is R|A|) -> {
|
||||
Int(1)
|
||||
}
|
||||
==($subj$, Q|B|) -> {
|
||||
Int(2)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public final fun test_2(base: R|Base?|): R|kotlin/Unit| {
|
||||
lval x: R|kotlin/Unit| = when (R|<local>/base|) {
|
||||
($subj$ is R|A|) -> {
|
||||
Int(1)
|
||||
}
|
||||
($subj$ is R|B|) -> {
|
||||
Int(2)
|
||||
}
|
||||
}
|
||||
|
||||
lval y: R|kotlin/Unit| = when (R|<local>/base|) {
|
||||
($subj$ is R|A|) -> {
|
||||
Int(1)
|
||||
}
|
||||
==($subj$, Q|B|) -> {
|
||||
Int(2)
|
||||
}
|
||||
}
|
||||
|
||||
lval z: R|kotlin/Int| = when (R|<local>/base|) {
|
||||
($subj$ is R|A|) -> {
|
||||
Int(1)
|
||||
}
|
||||
==($subj$, Q|B|) -> {
|
||||
Int(2)
|
||||
}
|
||||
==($subj$, Null(null)) -> {
|
||||
Int(3)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public final fun test_3(base: R|Base|): R|kotlin/Unit| {
|
||||
when (R|<local>/base|) {
|
||||
($subj$ is R|A|) -> {
|
||||
Int(1)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Vendored
+50
@@ -0,0 +1,50 @@
|
||||
// FILE: a.kt
|
||||
|
||||
sealed class Base
|
||||
|
||||
class A : Base
|
||||
|
||||
// FILE: b.kt
|
||||
|
||||
object B : Base()
|
||||
|
||||
// FILE: c.kt
|
||||
|
||||
fun test_1(base: Base) {
|
||||
val x = <!NO_ELSE_IN_WHEN!>when<!> (base) {
|
||||
is A -> 1
|
||||
}
|
||||
|
||||
val y = <!NO_ELSE_IN_WHEN!>when<!> (base) {
|
||||
B -> 1
|
||||
}
|
||||
|
||||
val z = when (base) {
|
||||
is A -> 1
|
||||
B -> 2
|
||||
}
|
||||
}
|
||||
|
||||
fun test_2(base: Base?) {
|
||||
val x = <!NO_ELSE_IN_WHEN!>when<!> (base) {
|
||||
is A -> 1
|
||||
is B -> 2
|
||||
}
|
||||
|
||||
val y = <!NO_ELSE_IN_WHEN!>when<!> (base) {
|
||||
is A -> 1
|
||||
B -> 2
|
||||
}
|
||||
|
||||
val z = when (base) {
|
||||
is A -> 1
|
||||
B -> 2
|
||||
null -> 3
|
||||
}
|
||||
}
|
||||
|
||||
fun test_3(base: Base) {
|
||||
when (base) {
|
||||
is A -> 1
|
||||
}
|
||||
}
|
||||
Vendored
+345
@@ -0,0 +1,345 @@
|
||||
digraph exhaustiveWhenAndDNNType_kt {
|
||||
graph [nodesep=3]
|
||||
node [shape=box penwidth=2]
|
||||
edge [penwidth=2]
|
||||
|
||||
subgraph cluster_0 {
|
||||
color=red
|
||||
0 [label="Enter class SomeEnum" style="filled" fillcolor=red];
|
||||
1 [label="Exit class SomeEnum" style="filled" fillcolor=red];
|
||||
}
|
||||
0 -> {1} [color=green];
|
||||
|
||||
subgraph cluster_1 {
|
||||
color=red
|
||||
2 [label="Enter function <init>" style="filled" fillcolor=red];
|
||||
3 [label="Delegated constructor call: super<R|kotlin/Enum<SomeEnum>|>()"];
|
||||
4 [label="Exit function <init>" style="filled" fillcolor=red];
|
||||
}
|
||||
2 -> {3};
|
||||
3 -> {4};
|
||||
|
||||
subgraph cluster_2 {
|
||||
color=red
|
||||
5 [label="Enter function values" style="filled" fillcolor=red];
|
||||
subgraph cluster_3 {
|
||||
color=blue
|
||||
6 [label="Enter block"];
|
||||
7 [label="Exit block"];
|
||||
}
|
||||
8 [label="Exit function values" style="filled" fillcolor=red];
|
||||
}
|
||||
5 -> {6};
|
||||
6 -> {7};
|
||||
7 -> {8};
|
||||
|
||||
subgraph cluster_4 {
|
||||
color=red
|
||||
9 [label="Enter function valueOf" style="filled" fillcolor=red];
|
||||
subgraph cluster_5 {
|
||||
color=blue
|
||||
10 [label="Enter block"];
|
||||
11 [label="Exit block"];
|
||||
}
|
||||
12 [label="Exit function valueOf" style="filled" fillcolor=red];
|
||||
}
|
||||
9 -> {10};
|
||||
10 -> {11};
|
||||
11 -> {12};
|
||||
|
||||
subgraph cluster_6 {
|
||||
color=red
|
||||
13 [label="Enter class B" style="filled" fillcolor=red];
|
||||
14 [label="Exit class B" style="filled" fillcolor=red];
|
||||
}
|
||||
13 -> {14} [color=green];
|
||||
|
||||
subgraph cluster_7 {
|
||||
color=red
|
||||
15 [label="Enter function <init>" style="filled" fillcolor=red];
|
||||
16 [label="Delegated constructor call: super<R|kotlin/Any|>()"];
|
||||
17 [label="Exit function <init>" style="filled" fillcolor=red];
|
||||
}
|
||||
15 -> {16};
|
||||
16 -> {17};
|
||||
|
||||
subgraph cluster_8 {
|
||||
color=red
|
||||
18 [label="Enter function takeB" style="filled" fillcolor=red];
|
||||
subgraph cluster_9 {
|
||||
color=blue
|
||||
19 [label="Enter block"];
|
||||
20 [label="Exit block"];
|
||||
}
|
||||
21 [label="Exit function takeB" style="filled" fillcolor=red];
|
||||
}
|
||||
18 -> {19};
|
||||
19 -> {20};
|
||||
20 -> {21};
|
||||
|
||||
subgraph cluster_10 {
|
||||
color=red
|
||||
22 [label="Enter function test_1" style="filled" fillcolor=red];
|
||||
subgraph cluster_11 {
|
||||
color=blue
|
||||
23 [label="Enter block"];
|
||||
24 [label="Access qualifier /SomeEnum"];
|
||||
25 [label="Access variable R|/SomeEnum.A1|"];
|
||||
26 [label="Variable declaration: lval flag: R|SomeEnum|"];
|
||||
subgraph cluster_12 {
|
||||
color=blue
|
||||
27 [label="Enter when"];
|
||||
28 [label="Access variable R|<local>/flag|"];
|
||||
29 [label="Check not null: R|<local>/flag|!!"];
|
||||
subgraph cluster_13 {
|
||||
color=blue
|
||||
30 [label="Enter when branch condition "];
|
||||
31 [label="Access qualifier /SomeEnum"];
|
||||
32 [label="Access variable R|/SomeEnum.A1|"];
|
||||
33 [label="Equality operator =="];
|
||||
34 [label="Exit when branch condition"];
|
||||
}
|
||||
subgraph cluster_14 {
|
||||
color=blue
|
||||
35 [label="Enter when branch condition "];
|
||||
36 [label="Access qualifier /SomeEnum"];
|
||||
37 [label="Access variable R|/SomeEnum.A2|"];
|
||||
38 [label="Equality operator =="];
|
||||
39 [label="Exit when branch condition"];
|
||||
}
|
||||
40 [label="Enter when branch result"];
|
||||
subgraph cluster_15 {
|
||||
color=blue
|
||||
41 [label="Enter block"];
|
||||
42 [label="Function call: R|/B.B|()"];
|
||||
43 [label="Exit block"];
|
||||
}
|
||||
44 [label="Exit when branch result"];
|
||||
45 [label="Enter when branch result"];
|
||||
subgraph cluster_16 {
|
||||
color=blue
|
||||
46 [label="Enter block"];
|
||||
47 [label="Function call: R|/B.B|()"];
|
||||
48 [label="Exit block"];
|
||||
}
|
||||
49 [label="Exit when branch result"];
|
||||
50 [label="Exit when"];
|
||||
}
|
||||
51 [label="Variable declaration: lval b: R|B|"];
|
||||
52 [label="Access variable R|<local>/b|"];
|
||||
53 [label="Function call: R|/takeB|(...)"];
|
||||
54 [label="Exit block"];
|
||||
}
|
||||
55 [label="Exit function test_1" style="filled" fillcolor=red];
|
||||
}
|
||||
22 -> {23};
|
||||
23 -> {24};
|
||||
24 -> {25};
|
||||
25 -> {26};
|
||||
26 -> {27};
|
||||
27 -> {28};
|
||||
28 -> {29};
|
||||
29 -> {30};
|
||||
30 -> {31};
|
||||
31 -> {32};
|
||||
32 -> {33};
|
||||
33 -> {34};
|
||||
34 -> {45 35};
|
||||
35 -> {36};
|
||||
36 -> {37};
|
||||
37 -> {38};
|
||||
38 -> {39};
|
||||
39 -> {40};
|
||||
40 -> {41};
|
||||
41 -> {42};
|
||||
42 -> {43};
|
||||
43 -> {44};
|
||||
44 -> {50};
|
||||
45 -> {46};
|
||||
46 -> {47};
|
||||
47 -> {48};
|
||||
48 -> {49};
|
||||
49 -> {50};
|
||||
50 -> {51};
|
||||
51 -> {52};
|
||||
52 -> {53};
|
||||
53 -> {54};
|
||||
54 -> {55};
|
||||
|
||||
subgraph cluster_17 {
|
||||
color=red
|
||||
56 [label="Enter function test_2" style="filled" fillcolor=red];
|
||||
subgraph cluster_18 {
|
||||
color=blue
|
||||
57 [label="Enter block"];
|
||||
58 [label="Access qualifier /SomeEnum"];
|
||||
59 [label="Access variable R|/SomeEnum.A1|"];
|
||||
60 [label="Variable declaration: lval flag: R|SomeEnum|"];
|
||||
subgraph cluster_19 {
|
||||
color=blue
|
||||
61 [label="Enter when"];
|
||||
62 [label="Access variable R|<local>/flag|"];
|
||||
63 [label="Check not null: R|<local>/flag|!!"];
|
||||
subgraph cluster_20 {
|
||||
color=blue
|
||||
64 [label="Enter when branch condition "];
|
||||
65 [label="Access qualifier /SomeEnum"];
|
||||
66 [label="Access variable R|/SomeEnum.A1|"];
|
||||
67 [label="Equality operator =="];
|
||||
68 [label="Exit when branch condition"];
|
||||
}
|
||||
subgraph cluster_21 {
|
||||
color=blue
|
||||
69 [label="Enter when branch condition "];
|
||||
70 [label="Access qualifier /SomeEnum"];
|
||||
71 [label="Access variable R|/SomeEnum.A2|"];
|
||||
72 [label="Equality operator =="];
|
||||
73 [label="Exit when branch condition"];
|
||||
}
|
||||
74 [label="Enter when branch result"];
|
||||
subgraph cluster_22 {
|
||||
color=blue
|
||||
75 [label="Enter block"];
|
||||
76 [label="Function call: R|/B.B|()"];
|
||||
77 [label="Exit block"];
|
||||
}
|
||||
78 [label="Exit when branch result"];
|
||||
79 [label="Enter when branch result"];
|
||||
subgraph cluster_23 {
|
||||
color=blue
|
||||
80 [label="Enter block"];
|
||||
81 [label="Function call: R|/B.B|()"];
|
||||
82 [label="Exit block"];
|
||||
}
|
||||
83 [label="Exit when branch result"];
|
||||
84 [label="Exit when"];
|
||||
}
|
||||
85 [label="Variable declaration: lval b: R|B|"];
|
||||
86 [label="Access variable R|<local>/b|"];
|
||||
87 [label="Function call: R|/takeB|(...)"];
|
||||
88 [label="Exit block"];
|
||||
}
|
||||
89 [label="Exit function test_2" style="filled" fillcolor=red];
|
||||
}
|
||||
56 -> {57};
|
||||
57 -> {58};
|
||||
58 -> {59};
|
||||
59 -> {60};
|
||||
60 -> {61};
|
||||
61 -> {62};
|
||||
62 -> {63};
|
||||
63 -> {64};
|
||||
64 -> {65};
|
||||
65 -> {66};
|
||||
66 -> {67};
|
||||
67 -> {68};
|
||||
68 -> {79 69};
|
||||
69 -> {70};
|
||||
70 -> {71};
|
||||
71 -> {72};
|
||||
72 -> {73};
|
||||
73 -> {74};
|
||||
74 -> {75};
|
||||
75 -> {76};
|
||||
76 -> {77};
|
||||
77 -> {78};
|
||||
78 -> {84};
|
||||
79 -> {80};
|
||||
80 -> {81};
|
||||
81 -> {82};
|
||||
82 -> {83};
|
||||
83 -> {84};
|
||||
84 -> {85};
|
||||
85 -> {86};
|
||||
86 -> {87};
|
||||
87 -> {88};
|
||||
88 -> {89};
|
||||
|
||||
subgraph cluster_24 {
|
||||
color=red
|
||||
90 [label="Enter function test_3" style="filled" fillcolor=red];
|
||||
subgraph cluster_25 {
|
||||
color=blue
|
||||
91 [label="Enter block"];
|
||||
92 [label="Access qualifier /SomeEnum"];
|
||||
93 [label="Access variable R|/SomeEnum.A1|"];
|
||||
94 [label="Variable declaration: lval flag: R|SomeEnum|"];
|
||||
subgraph cluster_26 {
|
||||
color=blue
|
||||
95 [label="Enter when"];
|
||||
96 [label="Access variable R|<local>/flag|"];
|
||||
subgraph cluster_27 {
|
||||
color=blue
|
||||
97 [label="Enter when branch condition "];
|
||||
98 [label="Access qualifier /SomeEnum"];
|
||||
99 [label="Access variable R|/SomeEnum.A1|"];
|
||||
100 [label="Equality operator =="];
|
||||
101 [label="Exit when branch condition"];
|
||||
}
|
||||
subgraph cluster_28 {
|
||||
color=blue
|
||||
102 [label="Enter when branch condition "];
|
||||
103 [label="Access qualifier /SomeEnum"];
|
||||
104 [label="Access variable R|/SomeEnum.A2|"];
|
||||
105 [label="Equality operator =="];
|
||||
106 [label="Exit when branch condition"];
|
||||
}
|
||||
107 [label="Enter when branch result"];
|
||||
subgraph cluster_29 {
|
||||
color=blue
|
||||
108 [label="Enter block"];
|
||||
109 [label="Function call: R|/B.B|()"];
|
||||
110 [label="Exit block"];
|
||||
}
|
||||
111 [label="Exit when branch result"];
|
||||
112 [label="Enter when branch result"];
|
||||
subgraph cluster_30 {
|
||||
color=blue
|
||||
113 [label="Enter block"];
|
||||
114 [label="Function call: R|/B.B|()"];
|
||||
115 [label="Exit block"];
|
||||
}
|
||||
116 [label="Exit when branch result"];
|
||||
117 [label="Exit when"];
|
||||
}
|
||||
118 [label="Variable declaration: lval b: R|B|"];
|
||||
119 [label="Access variable R|<local>/b|"];
|
||||
120 [label="Function call: R|/takeB|(...)"];
|
||||
121 [label="Exit block"];
|
||||
}
|
||||
122 [label="Exit function test_3" style="filled" fillcolor=red];
|
||||
}
|
||||
90 -> {91};
|
||||
91 -> {92};
|
||||
92 -> {93};
|
||||
93 -> {94};
|
||||
94 -> {95};
|
||||
95 -> {96};
|
||||
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 -> {117};
|
||||
112 -> {113};
|
||||
113 -> {114};
|
||||
114 -> {115};
|
||||
115 -> {116};
|
||||
116 -> {117};
|
||||
117 -> {118};
|
||||
118 -> {119};
|
||||
119 -> {120};
|
||||
120 -> {121};
|
||||
121 -> {122};
|
||||
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
FILE: exhaustiveWhenAndDNNType.kt
|
||||
public final enum class SomeEnum : R|kotlin/Enum<SomeEnum>| {
|
||||
private constructor(): R|SomeEnum| {
|
||||
super<R|kotlin/Enum<SomeEnum>|>()
|
||||
}
|
||||
|
||||
public final static enum entry A1: R|SomeEnum|
|
||||
public final static enum entry A2: R|SomeEnum|
|
||||
public final static fun values(): R|kotlin/Array<SomeEnum>| {
|
||||
}
|
||||
|
||||
public final static fun valueOf(value: R|kotlin/String|): R|SomeEnum| {
|
||||
}
|
||||
|
||||
}
|
||||
public final class B : R|kotlin/Any| {
|
||||
public constructor(): R|B| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
public final fun takeB(b: R|B|): R|kotlin/Unit| {
|
||||
}
|
||||
public final fun test_1(): R|kotlin/Unit| {
|
||||
lval flag: R|SomeEnum| = Q|SomeEnum|.R|/SomeEnum.A1|
|
||||
lval b: R|B| = when (R|<local>/flag|!!) {
|
||||
==($subj$, Q|SomeEnum|.R|/SomeEnum.A1|) -> {
|
||||
R|/B.B|()
|
||||
}
|
||||
==($subj$, Q|SomeEnum|.R|/SomeEnum.A2|) -> {
|
||||
R|/B.B|()
|
||||
}
|
||||
}
|
||||
|
||||
R|/takeB|(R|<local>/b|)
|
||||
}
|
||||
public final fun test_2(): R|kotlin/Unit| {
|
||||
lval flag: R|SomeEnum| = Q|SomeEnum|.R|/SomeEnum.A1|
|
||||
lval b: R|B| = when (R|<local>/flag|!!) {
|
||||
==($subj$, Q|SomeEnum|.R|/SomeEnum.A1|) -> {
|
||||
R|/B.B|()
|
||||
}
|
||||
==($subj$, Q|SomeEnum|.R|/SomeEnum.A2|) -> {
|
||||
R|/B.B|()
|
||||
}
|
||||
}
|
||||
|
||||
R|/takeB|(R|<local>/b|)
|
||||
}
|
||||
public final fun test_3(): R|kotlin/Unit| {
|
||||
lval flag: R|SomeEnum| = Q|SomeEnum|.R|/SomeEnum.A1|
|
||||
lval b: R|B| = when (R|<local>/flag|) {
|
||||
==($subj$, Q|SomeEnum|.R|/SomeEnum.A1|) -> {
|
||||
R|/B.B|()
|
||||
}
|
||||
==($subj$, Q|SomeEnum|.R|/SomeEnum.A2|) -> {
|
||||
R|/B.B|()
|
||||
}
|
||||
}
|
||||
|
||||
R|/takeB|(R|<local>/b|)
|
||||
}
|
||||
Vendored
+38
@@ -0,0 +1,38 @@
|
||||
// !DUMP_CFG
|
||||
// ISSUE: KT-37091
|
||||
|
||||
enum class SomeEnum {
|
||||
A1, A2;
|
||||
}
|
||||
|
||||
class B()
|
||||
|
||||
fun takeB(b: B) {}
|
||||
|
||||
fun test_1() {
|
||||
val flag = SomeEnum.A1
|
||||
val b: B = when (flag!!) {
|
||||
SomeEnum.A1 -> B()
|
||||
SomeEnum.A2 -> B()
|
||||
}
|
||||
takeB(b) // should be OK
|
||||
}
|
||||
|
||||
fun test_2() {
|
||||
val flag = SomeEnum.A1
|
||||
|
||||
val b = when (flag!!) {
|
||||
SomeEnum.A1 -> B()
|
||||
SomeEnum.A2 -> B()
|
||||
}
|
||||
takeB(b) // should be OK
|
||||
}
|
||||
|
||||
fun test_3() {
|
||||
val flag = SomeEnum.A1
|
||||
val b = when (flag) { //there is no null-assertion! , no explicit type
|
||||
SomeEnum.A1 -> B()
|
||||
SomeEnum.A2 -> B()
|
||||
}
|
||||
takeB(b) // should be OK
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
FILE: main.kt
|
||||
public final enum class E : R|kotlin/Enum<E>| {
|
||||
private constructor(): R|E| {
|
||||
super<R|kotlin/Enum<E>|>()
|
||||
}
|
||||
|
||||
public final static enum entry A: R|E|
|
||||
public final static enum entry B: R|E|
|
||||
public final static enum entry C: R|E|
|
||||
public final static fun values(): R|kotlin/Array<E>| {
|
||||
}
|
||||
|
||||
public final static fun valueOf(value: R|kotlin/String|): R|E| {
|
||||
}
|
||||
|
||||
}
|
||||
public final fun test_1(): R|kotlin/Unit| {
|
||||
lval e: R|ft<@FlexibleNullability E, E?>!| = Q|Utils|.R|/Utils.getEnum|()
|
||||
lval s: R|kotlin/String| = when (R|<local>/e|) {
|
||||
==($subj$, Null(null)) -> {
|
||||
^test_1 Unit
|
||||
}
|
||||
==($subj$, Q|E|.R|/E.A|) -> {
|
||||
String()
|
||||
}
|
||||
==($subj$, Q|E|.R|/E.B|) -> {
|
||||
String()
|
||||
}
|
||||
==($subj$, Q|E|.R|/E.C|) -> {
|
||||
String()
|
||||
}
|
||||
}
|
||||
|
||||
R|<local>/s|.R|kotlin/String.length|
|
||||
}
|
||||
public final fun test_2(): R|kotlin/Unit| {
|
||||
lval e: R|ft<@FlexibleNullability E, E?>!| = Q|Utils|.R|/Utils.getEnum|()
|
||||
lval s: R|kotlin/String| = when (R|<local>/e|) {
|
||||
==($subj$, Q|E|.R|/E.A|) -> {
|
||||
String()
|
||||
}
|
||||
==($subj$, Q|E|.R|/E.B|) -> {
|
||||
String()
|
||||
}
|
||||
==($subj$, Q|E|.R|/E.C|) -> {
|
||||
String()
|
||||
}
|
||||
}
|
||||
|
||||
R|<local>/s|.R|kotlin/String.length|
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
// IGNORE_LIGHT_TREE
|
||||
|
||||
// FILE: Utils.java
|
||||
|
||||
public class Utils {
|
||||
public static E getEnum() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
|
||||
enum class E {
|
||||
A, B, C
|
||||
}
|
||||
|
||||
fun test_1() {
|
||||
val e = Utils.getEnum()
|
||||
val s = when (e) {
|
||||
null -> return
|
||||
E.A -> ""
|
||||
E.B -> ""
|
||||
E.C -> ""
|
||||
}
|
||||
s.length
|
||||
}
|
||||
|
||||
fun test_2() {
|
||||
val e = Utils.getEnum()
|
||||
val s = when (e) {
|
||||
E.A -> ""
|
||||
E.B -> ""
|
||||
E.C -> ""
|
||||
}
|
||||
s.length
|
||||
}
|
||||
Vendored
+50
@@ -0,0 +1,50 @@
|
||||
FILE: exhaustiveness_boolean.kt
|
||||
public final fun test_1(b: R|kotlin/Boolean|): R|kotlin/Unit| {
|
||||
lval x: R|kotlin/Unit| = when (R|<local>/b|) {
|
||||
==($subj$, Boolean(true)) -> {
|
||||
Int(1)
|
||||
}
|
||||
}
|
||||
|
||||
lval y: R|kotlin/Int| = when (R|<local>/b|) {
|
||||
==($subj$, Boolean(true)) -> {
|
||||
Int(1)
|
||||
}
|
||||
==($subj$, Boolean(false)) -> {
|
||||
Int(2)
|
||||
}
|
||||
}
|
||||
|
||||
lval z: R|kotlin/Int| = when (R|<local>/b|) {
|
||||
==($subj$, Boolean(true)) -> {
|
||||
Int(1)
|
||||
}
|
||||
else -> {
|
||||
Int(2)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public final fun test_2(b: R|kotlin/Boolean?|): R|kotlin/Unit| {
|
||||
lval x: R|kotlin/Unit| = when (R|<local>/b|) {
|
||||
==($subj$, Boolean(true)) -> {
|
||||
Int(1)
|
||||
}
|
||||
==($subj$, Boolean(false)) -> {
|
||||
Int(2)
|
||||
}
|
||||
}
|
||||
|
||||
lval y: R|kotlin/Int| = when (R|<local>/b|) {
|
||||
==($subj$, Boolean(true)) -> {
|
||||
Int(1)
|
||||
}
|
||||
==($subj$, Boolean(false)) -> {
|
||||
Int(2)
|
||||
}
|
||||
==($subj$, Null(null)) -> {
|
||||
Int(3)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Vendored
+25
@@ -0,0 +1,25 @@
|
||||
fun test_1(b: Boolean) {
|
||||
val x = <!NO_ELSE_IN_WHEN!>when<!> (b) {
|
||||
true -> 1
|
||||
}
|
||||
val y = when (b) {
|
||||
true -> 1
|
||||
false -> 2
|
||||
}
|
||||
val z = when (b) {
|
||||
true -> 1
|
||||
else -> 2
|
||||
}
|
||||
}
|
||||
|
||||
fun test_2(b: Boolean?) {
|
||||
val x = <!NO_ELSE_IN_WHEN!>when<!> (b) {
|
||||
true -> 1
|
||||
false -> 2
|
||||
}
|
||||
val y = when (b) {
|
||||
true -> 1
|
||||
false -> 2
|
||||
null -> 3
|
||||
}
|
||||
}
|
||||
Vendored
+115
@@ -0,0 +1,115 @@
|
||||
FILE: exhaustiveness_enum.kt
|
||||
public final enum class Enum : R|kotlin/Enum<Enum>| {
|
||||
private constructor(): R|Enum| {
|
||||
super<R|kotlin/Enum<Enum>|>()
|
||||
}
|
||||
|
||||
public final static enum entry A: R|Enum|
|
||||
public final static enum entry B: R|Enum|
|
||||
public final static enum entry C: R|Enum|
|
||||
public final static fun values(): R|kotlin/Array<Enum>| {
|
||||
}
|
||||
|
||||
public final static fun valueOf(value: R|kotlin/String|): R|Enum| {
|
||||
}
|
||||
|
||||
}
|
||||
public final fun test_1(e: R|Enum|): R|kotlin/Unit| {
|
||||
lval a: R|kotlin/Unit| = when (R|<local>/e|) {
|
||||
==($subj$, Q|Enum|.R|/Enum.A|) -> {
|
||||
Int(1)
|
||||
}
|
||||
==($subj$, Q|Enum|.R|/Enum.B|) -> {
|
||||
Int(2)
|
||||
}
|
||||
}
|
||||
|
||||
lval b: R|kotlin/Unit| = when (R|<local>/e|) {
|
||||
==($subj$, Q|Enum|.R|/Enum.A|) -> {
|
||||
Int(1)
|
||||
}
|
||||
==($subj$, Q|Enum|.R|/Enum.B|) -> {
|
||||
Int(2)
|
||||
}
|
||||
($subj$ is R|kotlin/String|) -> {
|
||||
Int(3)
|
||||
}
|
||||
}
|
||||
|
||||
lval c: R|kotlin/Int| = when (R|<local>/e|) {
|
||||
==($subj$, Q|Enum|.R|/Enum.A|) -> {
|
||||
Int(1)
|
||||
}
|
||||
==($subj$, Q|Enum|.R|/Enum.B|) -> {
|
||||
Int(2)
|
||||
}
|
||||
==($subj$, Q|Enum|.R|/Enum.C|) -> {
|
||||
Int(3)
|
||||
}
|
||||
}
|
||||
|
||||
lval d: R|kotlin/Int| = when (R|<local>/e|) {
|
||||
==($subj$, Q|Enum|.R|/Enum.A|) -> {
|
||||
Int(1)
|
||||
}
|
||||
else -> {
|
||||
Int(2)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public final fun test_2(e: R|Enum?|): R|kotlin/Unit| {
|
||||
lval a: R|kotlin/Unit| = when (R|<local>/e|) {
|
||||
==($subj$, Q|Enum|.R|/Enum.A|) -> {
|
||||
Int(1)
|
||||
}
|
||||
==($subj$, Q|Enum|.R|/Enum.B|) -> {
|
||||
Int(2)
|
||||
}
|
||||
==($subj$, Q|Enum|.R|/Enum.C|) -> {
|
||||
Int(3)
|
||||
}
|
||||
}
|
||||
|
||||
lval a: R|kotlin/Int| = when (R|<local>/e|) {
|
||||
==($subj$, Q|Enum|.R|/Enum.A|) -> {
|
||||
Int(1)
|
||||
}
|
||||
==($subj$, Q|Enum|.R|/Enum.B|) -> {
|
||||
Int(2)
|
||||
}
|
||||
==($subj$, Q|Enum|.R|/Enum.C|) -> {
|
||||
Int(3)
|
||||
}
|
||||
==($subj$, Null(null)) -> {
|
||||
Int(4)
|
||||
}
|
||||
}
|
||||
|
||||
lval a: R|kotlin/Int| = when (R|<local>/e|) {
|
||||
==($subj$, Q|Enum|.R|/Enum.A|) -> {
|
||||
Int(1)
|
||||
}
|
||||
==($subj$, Q|Enum|.R|/Enum.B|) -> {
|
||||
Int(2)
|
||||
}
|
||||
==($subj$, Q|Enum|.R|/Enum.C|) -> {
|
||||
Int(3)
|
||||
}
|
||||
else -> {
|
||||
Int(4)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public final fun test_3(e: R|Enum|): R|kotlin/Unit| {
|
||||
lval a: R|kotlin/Int| = when (R|<local>/e|) {
|
||||
==($subj$, Q|Enum|.R|/Enum.A|) || ==($subj$, Q|Enum|.R|/Enum.B|) -> {
|
||||
Int(1)
|
||||
}
|
||||
==($subj$, Q|Enum|.R|/Enum.C|) -> {
|
||||
Int(2)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Vendored
+56
@@ -0,0 +1,56 @@
|
||||
enum class Enum {
|
||||
A, B, C
|
||||
}
|
||||
|
||||
fun test_1(e: Enum) {
|
||||
val a = <!NO_ELSE_IN_WHEN!>when<!> (e) {
|
||||
Enum.A -> 1
|
||||
Enum.B -> 2
|
||||
}
|
||||
|
||||
val b = <!NO_ELSE_IN_WHEN!>when<!> (e) {
|
||||
Enum.A -> 1
|
||||
Enum.B -> 2
|
||||
is String -> 3
|
||||
}
|
||||
|
||||
val c = when (e) {
|
||||
Enum.A -> 1
|
||||
Enum.B -> 2
|
||||
Enum.C -> 3
|
||||
}
|
||||
|
||||
val d = when (e) {
|
||||
Enum.A -> 1
|
||||
else -> 2
|
||||
}
|
||||
}
|
||||
|
||||
fun test_2(e: Enum?) {
|
||||
val a = <!NO_ELSE_IN_WHEN!>when<!> (e) {
|
||||
Enum.A -> 1
|
||||
Enum.B -> 2
|
||||
Enum.C -> 3
|
||||
}
|
||||
|
||||
val a = when (e) {
|
||||
Enum.A -> 1
|
||||
Enum.B -> 2
|
||||
Enum.C -> 3
|
||||
null -> 4
|
||||
}
|
||||
|
||||
val a = when (e) {
|
||||
Enum.A -> 1
|
||||
Enum.B -> 2
|
||||
Enum.C -> 3
|
||||
else -> 4
|
||||
}
|
||||
}
|
||||
|
||||
fun test_3(e: Enum) {
|
||||
val a = when (e) {
|
||||
Enum.A, Enum.B -> 1
|
||||
Enum.C -> 2
|
||||
}
|
||||
}
|
||||
compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enumJava.fir.txt
Vendored
+100
@@ -0,0 +1,100 @@
|
||||
FILE: main.kt
|
||||
public final fun test_1(e: R|JavaEnum|): R|kotlin/Unit| {
|
||||
lval a: R|ERROR CLASS: Unresolved name: plus| = when (R|<local>/e|) {
|
||||
==($subj$, Q|JavaEnum|.R|/JavaEnum.A|) -> {
|
||||
Int(1)
|
||||
}
|
||||
==($subj$, Q|JavaEnum|.R|/JavaEnum.B|) -> {
|
||||
Int(2)
|
||||
}
|
||||
}
|
||||
.<Unresolved name: plus>#(Int(0))
|
||||
lval b: R|ERROR CLASS: Unresolved name: plus| = when (R|<local>/e|) {
|
||||
==($subj$, Q|JavaEnum|.R|/JavaEnum.A|) -> {
|
||||
Int(1)
|
||||
}
|
||||
==($subj$, Q|JavaEnum|.R|/JavaEnum.B|) -> {
|
||||
Int(2)
|
||||
}
|
||||
($subj$ is R|kotlin/String|) -> {
|
||||
Int(3)
|
||||
}
|
||||
}
|
||||
.<Unresolved name: plus>#(Int(0))
|
||||
lval c: R|kotlin/Int| = when (R|<local>/e|) {
|
||||
==($subj$, Q|JavaEnum|.R|/JavaEnum.A|) -> {
|
||||
Int(1)
|
||||
}
|
||||
==($subj$, Q|JavaEnum|.R|/JavaEnum.B|) -> {
|
||||
Int(2)
|
||||
}
|
||||
==($subj$, Q|JavaEnum|.R|/JavaEnum.C|) -> {
|
||||
Int(3)
|
||||
}
|
||||
}
|
||||
.R|kotlin/Int.plus|(Int(0))
|
||||
lval d: R|kotlin/Int| = when (R|<local>/e|) {
|
||||
==($subj$, Q|JavaEnum|.R|/JavaEnum.A|) -> {
|
||||
Int(1)
|
||||
}
|
||||
else -> {
|
||||
Int(2)
|
||||
}
|
||||
}
|
||||
.R|kotlin/Int.plus|(Int(0))
|
||||
}
|
||||
public final fun test_2(e: R|JavaEnum?|): R|kotlin/Unit| {
|
||||
lval a: R|ERROR CLASS: Unresolved name: plus| = when (R|<local>/e|) {
|
||||
==($subj$, Q|JavaEnum|.R|/JavaEnum.A|) -> {
|
||||
Int(1)
|
||||
}
|
||||
==($subj$, Q|JavaEnum|.R|/JavaEnum.B|) -> {
|
||||
Int(2)
|
||||
}
|
||||
==($subj$, Q|JavaEnum|.R|/JavaEnum.C|) -> {
|
||||
Int(3)
|
||||
}
|
||||
}
|
||||
.<Unresolved name: plus>#(Int(0))
|
||||
lval a: R|kotlin/Int| = when (R|<local>/e|) {
|
||||
==($subj$, Q|JavaEnum|.R|/JavaEnum.A|) -> {
|
||||
Int(1)
|
||||
}
|
||||
==($subj$, Q|JavaEnum|.R|/JavaEnum.B|) -> {
|
||||
Int(2)
|
||||
}
|
||||
==($subj$, Q|JavaEnum|.R|/JavaEnum.C|) -> {
|
||||
Int(3)
|
||||
}
|
||||
==($subj$, Null(null)) -> {
|
||||
Int(4)
|
||||
}
|
||||
}
|
||||
.R|kotlin/Int.plus|(Int(0))
|
||||
lval a: R|kotlin/Int| = when (R|<local>/e|) {
|
||||
==($subj$, Q|JavaEnum|.R|/JavaEnum.A|) -> {
|
||||
Int(1)
|
||||
}
|
||||
==($subj$, Q|JavaEnum|.R|/JavaEnum.B|) -> {
|
||||
Int(2)
|
||||
}
|
||||
==($subj$, Q|JavaEnum|.R|/JavaEnum.C|) -> {
|
||||
Int(3)
|
||||
}
|
||||
else -> {
|
||||
Int(4)
|
||||
}
|
||||
}
|
||||
.R|kotlin/Int.plus|(Int(0))
|
||||
}
|
||||
public final fun test_3(e: R|JavaEnum|): R|kotlin/Unit| {
|
||||
lval a: R|kotlin/Int| = when (R|<local>/e|) {
|
||||
==($subj$, Q|JavaEnum|.R|/JavaEnum.A|) || ==($subj$, Q|JavaEnum|.R|/JavaEnum.B|) -> {
|
||||
Int(1)
|
||||
}
|
||||
==($subj$, Q|JavaEnum|.R|/JavaEnum.C|) -> {
|
||||
Int(2)
|
||||
}
|
||||
}
|
||||
.R|kotlin/Int.plus|(Int(0))
|
||||
}
|
||||
Vendored
+60
@@ -0,0 +1,60 @@
|
||||
// FILE: JavaEnum.java
|
||||
public enum JavaEnum {
|
||||
A, B, C;
|
||||
|
||||
public int i = 0;
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
fun test_1(e: JavaEnum) {
|
||||
val a = <!NO_ELSE_IN_WHEN!>when<!> (e) {
|
||||
JavaEnum.A -> 1
|
||||
JavaEnum.B -> 2
|
||||
}.<!UNRESOLVED_REFERENCE{LT}!><!UNRESOLVED_REFERENCE{PSI}!>plus<!>(0)<!>
|
||||
|
||||
val b = <!NO_ELSE_IN_WHEN!>when<!> (e) {
|
||||
JavaEnum.A -> 1
|
||||
JavaEnum.B -> 2
|
||||
is String -> 3
|
||||
}.<!UNRESOLVED_REFERENCE{LT}!><!UNRESOLVED_REFERENCE{PSI}!>plus<!>(0)<!>
|
||||
|
||||
val c = when (e) {
|
||||
JavaEnum.A -> 1
|
||||
JavaEnum.B -> 2
|
||||
JavaEnum.C -> 3
|
||||
}.plus(0)
|
||||
|
||||
val d = when (e) {
|
||||
JavaEnum.A -> 1
|
||||
else -> 2
|
||||
}.plus(0)
|
||||
}
|
||||
|
||||
fun test_2(e: JavaEnum?) {
|
||||
val a = <!NO_ELSE_IN_WHEN!>when<!> (e) {
|
||||
JavaEnum.A -> 1
|
||||
JavaEnum.B -> 2
|
||||
JavaEnum.C -> 3
|
||||
}.<!UNRESOLVED_REFERENCE{LT}!><!UNRESOLVED_REFERENCE{PSI}!>plus<!>(0)<!>
|
||||
|
||||
val a = when (e) {
|
||||
JavaEnum.A -> 1
|
||||
JavaEnum.B -> 2
|
||||
JavaEnum.C -> 3
|
||||
null -> 4
|
||||
}.plus(0)
|
||||
|
||||
val a = when (e) {
|
||||
JavaEnum.A -> 1
|
||||
JavaEnum.B -> 2
|
||||
JavaEnum.C -> 3
|
||||
else -> 4
|
||||
}.plus(0)
|
||||
}
|
||||
|
||||
fun test_3(e: JavaEnum) {
|
||||
val a = when (e) {
|
||||
JavaEnum.A, JavaEnum.B -> 1
|
||||
JavaEnum.C -> 2
|
||||
}.plus(0)
|
||||
}
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
FILE: exhaustiveness_sealedClass.kt
|
||||
public sealed class Base : R|kotlin/Any| {
|
||||
private constructor(): R|Base| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public final class A : R|Base| {
|
||||
public constructor(): R|Base.A| {
|
||||
super<R|Base|>()
|
||||
}
|
||||
|
||||
public final class B : R|Base| {
|
||||
public constructor(): R|Base.A.B| {
|
||||
super<R|Base|>()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
public final class C : R|Base| {
|
||||
public constructor(): R|C| {
|
||||
super<R|Base|>()
|
||||
}
|
||||
|
||||
}
|
||||
public final fun test_1(e: R|Base|): R|kotlin/Unit| {
|
||||
lval a: R|kotlin/Unit| = when (R|<local>/e|) {
|
||||
($subj$ is R|Base.A|) -> {
|
||||
Int(1)
|
||||
}
|
||||
($subj$ is R|Base.A.B|) -> {
|
||||
Int(2)
|
||||
}
|
||||
}
|
||||
|
||||
lval b: R|kotlin/Unit| = when (R|<local>/e|) {
|
||||
($subj$ is R|Base.A|) -> {
|
||||
Int(1)
|
||||
}
|
||||
($subj$ is R|Base.A.B|) -> {
|
||||
Int(2)
|
||||
}
|
||||
($subj$ is R|kotlin/String|) -> {
|
||||
Int(3)
|
||||
}
|
||||
}
|
||||
|
||||
lval c: R|kotlin/Int| = when (R|<local>/e|) {
|
||||
($subj$ is R|Base.A|) -> {
|
||||
Int(1)
|
||||
}
|
||||
($subj$ is R|Base.A.B|) -> {
|
||||
Int(2)
|
||||
}
|
||||
($subj$ is R|C|) -> {
|
||||
Int(3)
|
||||
}
|
||||
}
|
||||
|
||||
lval d: R|kotlin/Int| = when (R|<local>/e|) {
|
||||
($subj$ is R|Base.A|) -> {
|
||||
Int(1)
|
||||
}
|
||||
else -> {
|
||||
Int(2)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public final fun test_2(e: R|Base?|): R|kotlin/Unit| {
|
||||
lval a: R|kotlin/Unit| = when (R|<local>/e|) {
|
||||
($subj$ is R|Base.A|) -> {
|
||||
Int(1)
|
||||
}
|
||||
($subj$ is R|Base.A.B|) -> {
|
||||
Int(2)
|
||||
}
|
||||
($subj$ is R|C|) -> {
|
||||
Int(3)
|
||||
}
|
||||
}
|
||||
|
||||
lval b: R|kotlin/Int| = when (R|<local>/e|) {
|
||||
($subj$ is R|Base.A|) -> {
|
||||
Int(1)
|
||||
}
|
||||
($subj$ is R|Base.A.B|) -> {
|
||||
Int(2)
|
||||
}
|
||||
($subj$ is R|C|) -> {
|
||||
Int(3)
|
||||
}
|
||||
==($subj$, Null(null)) -> {
|
||||
Int(4)
|
||||
}
|
||||
}
|
||||
|
||||
lval c: R|kotlin/Int| = when (R|<local>/e|) {
|
||||
($subj$ is R|Base.A|) -> {
|
||||
Int(1)
|
||||
}
|
||||
($subj$ is R|Base.A.B|) -> {
|
||||
Int(2)
|
||||
}
|
||||
($subj$ is R|C|) -> {
|
||||
Int(3)
|
||||
}
|
||||
else -> {
|
||||
Int(4)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public final fun test_3(e: R|Base|): R|kotlin/Unit| {
|
||||
lval a: R|kotlin/Int| = when (R|<local>/e|) {
|
||||
($subj$ is R|Base.A|) || ($subj$ is R|Base.A.B|) -> {
|
||||
Int(1)
|
||||
}
|
||||
($subj$ is R|C|) -> {
|
||||
Int(2)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Vendored
+60
@@ -0,0 +1,60 @@
|
||||
sealed class Base {
|
||||
class A : Base() {
|
||||
class B : Base()
|
||||
}
|
||||
}
|
||||
|
||||
class C : Base()
|
||||
|
||||
fun test_1(e: Base) {
|
||||
val a = <!NO_ELSE_IN_WHEN!>when<!> (e) {
|
||||
is Base.A -> 1
|
||||
is Base.A.B -> 2
|
||||
}
|
||||
|
||||
val b = <!NO_ELSE_IN_WHEN!>when<!> (e) {
|
||||
is Base.A -> 1
|
||||
is Base.A.B -> 2
|
||||
is String -> 3
|
||||
}
|
||||
|
||||
val c = when (e) {
|
||||
is Base.A -> 1
|
||||
is Base.A.B -> 2
|
||||
is C -> 3
|
||||
}
|
||||
|
||||
val d = when (e) {
|
||||
is Base.A -> 1
|
||||
else -> 2
|
||||
}
|
||||
}
|
||||
|
||||
fun test_2(e: Base?) {
|
||||
val a = <!NO_ELSE_IN_WHEN!>when<!> (e) {
|
||||
is Base.A -> 1
|
||||
is Base.A.B -> 2
|
||||
is C -> 3
|
||||
}
|
||||
|
||||
val b = when (e) {
|
||||
is Base.A -> 1
|
||||
is Base.A.B -> 2
|
||||
is C -> 3
|
||||
null -> 4
|
||||
}
|
||||
|
||||
val c = when (e) {
|
||||
is Base.A -> 1
|
||||
is Base.A.B -> 2
|
||||
is C -> 3
|
||||
else -> 4
|
||||
}
|
||||
}
|
||||
|
||||
fun test_3(e: Base) {
|
||||
val a = when (e) {
|
||||
is Base.A, is Base.A.B -> 1
|
||||
is C -> 2
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
FILE: exhaustiveness_sealedObject.kt
|
||||
public sealed class A : R|kotlin/Any| {
|
||||
private constructor(): R|A| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
public final class B : R|A| {
|
||||
public constructor(): R|B| {
|
||||
super<R|A|>()
|
||||
}
|
||||
|
||||
}
|
||||
public final object C : R|A| {
|
||||
private constructor(): R|C| {
|
||||
super<R|A|>()
|
||||
}
|
||||
|
||||
}
|
||||
public final fun takeString(s: R|kotlin/String|): R|kotlin/Unit| {
|
||||
}
|
||||
public final fun test_1(a: R|A|): R|kotlin/Unit| {
|
||||
lval s: R|kotlin/String| = when (R|<local>/a|) {
|
||||
($subj$ is R|B|) -> {
|
||||
String()
|
||||
}
|
||||
($subj$ is R|C|) -> {
|
||||
String()
|
||||
}
|
||||
}
|
||||
|
||||
R|/takeString|(R|<local>/s|)
|
||||
}
|
||||
public final fun test_2(a: R|A|): R|kotlin/Unit| {
|
||||
lval s: R|kotlin/String| = when (R|<local>/a|) {
|
||||
($subj$ is R|B|) -> {
|
||||
String()
|
||||
}
|
||||
==($subj$, Q|C|) -> {
|
||||
String()
|
||||
}
|
||||
}
|
||||
|
||||
R|/takeString|(R|<local>/s|)
|
||||
}
|
||||
Vendored
+24
@@ -0,0 +1,24 @@
|
||||
// ISSUE: KT-37488
|
||||
|
||||
sealed class A
|
||||
|
||||
class B : A()
|
||||
object C : A()
|
||||
|
||||
fun takeString(s: String) {}
|
||||
|
||||
fun test_1(a: A) {
|
||||
val s = when(a) {
|
||||
is B -> ""
|
||||
is C -> ""
|
||||
}
|
||||
takeString(s)
|
||||
}
|
||||
|
||||
fun test_2(a: A) {
|
||||
val s = when(a) {
|
||||
is B -> ""
|
||||
C -> ""
|
||||
}
|
||||
takeString(s)
|
||||
}
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
FILE: exhaustiveness_sealedSubClass.kt
|
||||
public sealed class A : R|kotlin/Any| {
|
||||
private constructor(): R|A| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
public sealed class B : R|A| {
|
||||
private constructor(): R|B| {
|
||||
super<R|A|>()
|
||||
}
|
||||
|
||||
}
|
||||
public final class C : R|A| {
|
||||
public constructor(): R|C| {
|
||||
super<R|A|>()
|
||||
}
|
||||
|
||||
}
|
||||
public sealed class D : R|B| {
|
||||
private constructor(): R|D| {
|
||||
super<R|B|>()
|
||||
}
|
||||
|
||||
}
|
||||
public sealed class E : R|B| {
|
||||
private constructor(): R|E| {
|
||||
super<R|B|>()
|
||||
}
|
||||
|
||||
}
|
||||
public final fun test_1(e: R|A|): R|kotlin/Unit| {
|
||||
lval a: R|kotlin/Int| = when (R|<local>/e|) {
|
||||
($subj$ is R|C|) -> {
|
||||
Int(1)
|
||||
}
|
||||
($subj$ is R|D|) -> {
|
||||
Int(2)
|
||||
}
|
||||
($subj$ is R|E|) -> {
|
||||
Int(3)
|
||||
}
|
||||
}
|
||||
.R|kotlin/Int.plus|(Int(0))
|
||||
lval b: R|kotlin/Int| = when (R|<local>/e|) {
|
||||
($subj$ is R|B|) -> {
|
||||
Int(1)
|
||||
}
|
||||
($subj$ is R|C|) -> {
|
||||
Int(2)
|
||||
}
|
||||
}
|
||||
.R|kotlin/Int.plus|(Int(0))
|
||||
lval c: R|kotlin/Int| = when (R|<local>/e|) {
|
||||
($subj$ is R|B|) -> {
|
||||
Int(1)
|
||||
}
|
||||
($subj$ is R|C|) -> {
|
||||
Int(2)
|
||||
}
|
||||
($subj$ is R|E|) -> {
|
||||
Int(3)
|
||||
}
|
||||
($subj$ is R|D|) -> {
|
||||
Int(4)
|
||||
}
|
||||
}
|
||||
.R|kotlin/Int.plus|(Int(0))
|
||||
lval d: R|kotlin/Int| = when (R|<local>/e|) {
|
||||
($subj$ is R|E|) -> {
|
||||
Int(1)
|
||||
}
|
||||
($subj$ is R|A|) -> {
|
||||
Int(2)
|
||||
}
|
||||
}
|
||||
.R|kotlin/Int.plus|(Int(0))
|
||||
}
|
||||
public final fun test_2(e: R|A|): R|kotlin/Unit| {
|
||||
lval a: R|ERROR CLASS: Unresolved name: plus| = when (R|<local>/e|) {
|
||||
($subj$ is R|D|) -> {
|
||||
Int(1)
|
||||
}
|
||||
($subj$ is R|E|) -> {
|
||||
Int(2)
|
||||
}
|
||||
}
|
||||
.<Unresolved name: plus>#(Int(0))
|
||||
lval b: R|ERROR CLASS: Unresolved name: plus| = when (R|<local>/e|) {
|
||||
($subj$ is R|B|) -> {
|
||||
Int(1)
|
||||
}
|
||||
($subj$ is R|D|) -> {
|
||||
Int(2)
|
||||
}
|
||||
($subj$ is R|E|) -> {
|
||||
Int(3)
|
||||
}
|
||||
}
|
||||
.<Unresolved name: plus>#(Int(0))
|
||||
lval c: R|ERROR CLASS: Unresolved name: plus| = when (R|<local>/e|) {
|
||||
($subj$ is R|B|) -> {
|
||||
Int(1)
|
||||
}
|
||||
($subj$ is R|D|) -> {
|
||||
Int(2)
|
||||
}
|
||||
}
|
||||
.<Unresolved name: plus>#(Int(0))
|
||||
lval d: R|ERROR CLASS: Unresolved name: plus| = when (R|<local>/e|) {
|
||||
($subj$ is R|C|) -> {
|
||||
Int(1)
|
||||
}
|
||||
}
|
||||
.<Unresolved name: plus>#(Int(0))
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
sealed class A
|
||||
|
||||
sealed class B : A()
|
||||
class C : A()
|
||||
|
||||
sealed class D : B()
|
||||
sealed class E : B()
|
||||
|
||||
fun test_1(e: A) {
|
||||
val a = when (e) {
|
||||
is C -> 1
|
||||
is D -> 2
|
||||
is E -> 3
|
||||
}.plus(0)
|
||||
|
||||
val b = when (e) {
|
||||
is B -> 1
|
||||
is C -> 2
|
||||
}.plus(0)
|
||||
|
||||
val c = when (e) {
|
||||
is B -> 1
|
||||
is C -> 2
|
||||
is E -> 3
|
||||
is D -> 4
|
||||
}.plus(0)
|
||||
|
||||
val d = when (e) {
|
||||
is E -> 1
|
||||
is A -> 2
|
||||
}.plus(0)
|
||||
}
|
||||
|
||||
fun test_2(e: A) {
|
||||
val a = <!NO_ELSE_IN_WHEN!>when<!> (e) {
|
||||
is D -> 1
|
||||
is E -> 2
|
||||
}.<!UNRESOLVED_REFERENCE{LT}!><!UNRESOLVED_REFERENCE{PSI}!>plus<!>(0)<!>
|
||||
|
||||
val b = <!NO_ELSE_IN_WHEN!>when<!> (e) {
|
||||
is B -> 1
|
||||
is D -> 2
|
||||
is E -> 3
|
||||
}.<!UNRESOLVED_REFERENCE{LT}!><!UNRESOLVED_REFERENCE{PSI}!>plus<!>(0)<!>
|
||||
|
||||
val c = <!NO_ELSE_IN_WHEN!>when<!> (e) {
|
||||
is B -> 1
|
||||
is D -> 2
|
||||
}.<!UNRESOLVED_REFERENCE{LT}!><!UNRESOLVED_REFERENCE{PSI}!>plus<!>(0)<!>
|
||||
|
||||
val d = <!NO_ELSE_IN_WHEN!>when<!> (e) {
|
||||
is C -> 1
|
||||
}.<!UNRESOLVED_REFERENCE{LT}!><!UNRESOLVED_REFERENCE{PSI}!>plus<!>(0)<!>
|
||||
}
|
||||
Reference in New Issue
Block a user