[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
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
fun test_1(b: Boolean) {
|
||||
val x = when (b) {
|
||||
val x = <!NO_ELSE_IN_WHEN!>when<!> (b) {
|
||||
true -> 1
|
||||
}
|
||||
val y = when (b) {
|
||||
@@ -13,7 +13,7 @@ fun test_1(b: Boolean) {
|
||||
}
|
||||
|
||||
fun test_2(b: Boolean?) {
|
||||
val x = when (b) {
|
||||
val x = <!NO_ELSE_IN_WHEN!>when<!> (b) {
|
||||
true -> 1
|
||||
false -> 2
|
||||
}
|
||||
+3
-3
@@ -3,12 +3,12 @@ enum class Enum {
|
||||
}
|
||||
|
||||
fun test_1(e: Enum) {
|
||||
val a = when (e) {
|
||||
val a = <!NO_ELSE_IN_WHEN!>when<!> (e) {
|
||||
Enum.A -> 1
|
||||
Enum.B -> 2
|
||||
}
|
||||
|
||||
val b = when (e) {
|
||||
val b = <!NO_ELSE_IN_WHEN!>when<!> (e) {
|
||||
Enum.A -> 1
|
||||
Enum.B -> 2
|
||||
is String -> 3
|
||||
@@ -27,7 +27,7 @@ fun test_1(e: Enum) {
|
||||
}
|
||||
|
||||
fun test_2(e: Enum?) {
|
||||
val a = when (e) {
|
||||
val a = <!NO_ELSE_IN_WHEN!>when<!> (e) {
|
||||
Enum.A -> 1
|
||||
Enum.B -> 2
|
||||
Enum.C -> 3
|
||||
+3
-3
@@ -7,12 +7,12 @@ public enum JavaEnum {
|
||||
|
||||
// FILE: main.kt
|
||||
fun test_1(e: JavaEnum) {
|
||||
val a = when (e) {
|
||||
val a = <!NO_ELSE_IN_WHEN!>when<!> (e) {
|
||||
JavaEnum.A -> 1
|
||||
JavaEnum.B -> 2
|
||||
}.<!UNRESOLVED_REFERENCE{LT}!><!UNRESOLVED_REFERENCE{PSI}!>plus<!>(0)<!>
|
||||
|
||||
val b = when (e) {
|
||||
val b = <!NO_ELSE_IN_WHEN!>when<!> (e) {
|
||||
JavaEnum.A -> 1
|
||||
JavaEnum.B -> 2
|
||||
is String -> 3
|
||||
@@ -31,7 +31,7 @@ fun test_1(e: JavaEnum) {
|
||||
}
|
||||
|
||||
fun test_2(e: JavaEnum?) {
|
||||
val a = when (e) {
|
||||
val a = <!NO_ELSE_IN_WHEN!>when<!> (e) {
|
||||
JavaEnum.A -> 1
|
||||
JavaEnum.B -> 2
|
||||
JavaEnum.C -> 3
|
||||
+3
-3
@@ -7,12 +7,12 @@ sealed class Base {
|
||||
class C : Base()
|
||||
|
||||
fun test_1(e: Base) {
|
||||
val a = when (e) {
|
||||
val a = <!NO_ELSE_IN_WHEN!>when<!> (e) {
|
||||
is Base.A -> 1
|
||||
is Base.A.B -> 2
|
||||
}
|
||||
|
||||
val b = when (e) {
|
||||
val b = <!NO_ELSE_IN_WHEN!>when<!> (e) {
|
||||
is Base.A -> 1
|
||||
is Base.A.B -> 2
|
||||
is String -> 3
|
||||
@@ -31,7 +31,7 @@ fun test_1(e: Base) {
|
||||
}
|
||||
|
||||
fun test_2(e: Base?) {
|
||||
val a = when (e) {
|
||||
val a = <!NO_ELSE_IN_WHEN!>when<!> (e) {
|
||||
is Base.A -> 1
|
||||
is Base.A.B -> 2
|
||||
is C -> 3
|
||||
+4
-4
@@ -32,23 +32,23 @@ fun test_1(e: A) {
|
||||
}
|
||||
|
||||
fun test_2(e: A) {
|
||||
val a = when (e) {
|
||||
val a = <!NO_ELSE_IN_WHEN!>when<!> (e) {
|
||||
is D -> 1
|
||||
is E -> 2
|
||||
}.<!UNRESOLVED_REFERENCE{LT}!><!UNRESOLVED_REFERENCE{PSI}!>plus<!>(0)<!>
|
||||
|
||||
val b = when (e) {
|
||||
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 = when (e) {
|
||||
val c = <!NO_ELSE_IN_WHEN!>when<!> (e) {
|
||||
is B -> 1
|
||||
is D -> 2
|
||||
}.<!UNRESOLVED_REFERENCE{LT}!><!UNRESOLVED_REFERENCE{PSI}!>plus<!>(0)<!>
|
||||
|
||||
val d = when (e) {
|
||||
val d = <!NO_ELSE_IN_WHEN!>when<!> (e) {
|
||||
is C -> 1
|
||||
}.<!UNRESOLVED_REFERENCE{LT}!><!UNRESOLVED_REFERENCE{PSI}!>plus<!>(0)<!>
|
||||
}
|
||||
@@ -16,12 +16,12 @@ fun get(f: Boolean) = if (f) {A.A1} else {""}
|
||||
<!CONFLICTING_OVERLOADS!>fun case2()<!> {
|
||||
|
||||
val flag: Any = get(false) //string
|
||||
val l1 = when (flag!!) { // should be NO_ELSE_IN_WHEN
|
||||
val l1 = <!NO_ELSE_IN_WHEN!>when<!> (flag!!) { // should be NO_ELSE_IN_WHEN
|
||||
A.A1 -> B()
|
||||
A.A2 -> B()
|
||||
}
|
||||
|
||||
val l2 = when (flag) {// should be NO_ELSE_IN_WHEN
|
||||
val l2 = <!NO_ELSE_IN_WHEN!>when<!> (flag) {// should be NO_ELSE_IN_WHEN
|
||||
A.A1 -> B()
|
||||
A.A2 -> B()
|
||||
}
|
||||
@@ -30,12 +30,12 @@ fun get(f: Boolean) = if (f) {A.A1} else {""}
|
||||
<!CONFLICTING_OVERLOADS!>fun case2()<!> {
|
||||
|
||||
val flag: Any = get(true) //A
|
||||
val l1 = when (flag!!) {// should be NO_ELSE_IN_WHEN
|
||||
val l1 = <!NO_ELSE_IN_WHEN!>when<!> (flag!!) {// should be NO_ELSE_IN_WHEN
|
||||
A.A1 -> B()
|
||||
A.A2 -> B()
|
||||
}
|
||||
|
||||
val l2 = when (flag) {// should be NO_ELSE_IN_WHEN
|
||||
val l2 = <!NO_ELSE_IN_WHEN!>when<!> (flag) {// should be NO_ELSE_IN_WHEN
|
||||
A.A1 -> B()
|
||||
A.A2 -> B()
|
||||
}
|
||||
@@ -44,12 +44,12 @@ fun get(f: Boolean) = if (f) {A.A1} else {""}
|
||||
fun case3() {
|
||||
|
||||
val flag = "" //A
|
||||
val l1 = when (flag!!) {// should be NO_ELSE_IN_WHEN
|
||||
val l1 = <!NO_ELSE_IN_WHEN!>when<!> (flag!!) {// should be NO_ELSE_IN_WHEN
|
||||
A.A1 -> B() //should be INCOMPATIBLE_TYPES
|
||||
A.A2 -> B() //should be INCOMPATIBLE_TYPES
|
||||
}
|
||||
|
||||
val l2 = when (flag) {// should be NO_ELSE_IN_WHEN
|
||||
val l2 = <!NO_ELSE_IN_WHEN!>when<!> (flag) {// should be NO_ELSE_IN_WHEN
|
||||
A.A1 -> B() //should be INCOMPATIBLE_TYPES
|
||||
A.A2 -> B() //should be INCOMPATIBLE_TYPES
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user