[FIR] Report NON_EXHAUSTIVE_WHEN_STATEMENT/NO_ELSE_IN_WHEN for when's on logical types
^KT-47709 In Progress
This commit is contained in:
committed by
teamcityserver
parent
ef635f6a96
commit
a6edd852ff
@@ -1,15 +0,0 @@
|
||||
//FILE: foo.kt
|
||||
fun main() {
|
||||
val c: Type
|
||||
when (<!UNINITIALIZED_VARIABLE!>c<!>) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//FILE: Type.java
|
||||
public enum Type {
|
||||
TYPE,
|
||||
NO_TYPE;
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
//FILE: foo.kt
|
||||
fun main() {
|
||||
val c: Type
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VALUE
|
||||
|
||||
fun foo(f: Boolean): Int {
|
||||
val i: Int
|
||||
when (f) {
|
||||
true -> i = 1
|
||||
}
|
||||
<!VAL_REASSIGNMENT!>i<!> = 3
|
||||
return i
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -UNUSED_VALUE
|
||||
|
||||
fun foo(f: Boolean): Int {
|
||||
|
||||
@@ -7,7 +7,7 @@ fun foo(my: My) {
|
||||
if (my.x != null) {
|
||||
// my.x should be smart-cast
|
||||
if (my.x) doIt()
|
||||
when (my.x) {
|
||||
<!NON_EXHAUSTIVE_WHEN_STATEMENT!>when<!> (my.x) {
|
||||
true -> doIt()
|
||||
}
|
||||
when {
|
||||
@@ -20,11 +20,11 @@ fun bar(x: Boolean?) {
|
||||
if (x != null) {
|
||||
// x should be smart-cast
|
||||
if (x) doIt()
|
||||
when (x) {
|
||||
<!NON_EXHAUSTIVE_WHEN_STATEMENT!>when<!> (x) {
|
||||
true -> doIt()
|
||||
}
|
||||
when {
|
||||
x -> doIt()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ fun bar(a: Boolean, b: Boolean): Int {
|
||||
if (a) {
|
||||
x = 1
|
||||
}
|
||||
when (b) {
|
||||
<!NON_EXHAUSTIVE_WHEN_STATEMENT!>when<!> (b) {
|
||||
false -> <!VAL_REASSIGNMENT!>x<!> = 3
|
||||
}
|
||||
return <!UNINITIALIZED_VARIABLE!>x<!>
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ fun bar(a: Boolean, b: Boolean): Int {
|
||||
if (a) {
|
||||
x = 1
|
||||
}
|
||||
when (b) {
|
||||
<!NON_EXHAUSTIVE_WHEN_STATEMENT!>when<!> (b) {
|
||||
false -> x = 3
|
||||
}
|
||||
return <!UNINITIALIZED_VARIABLE!>x<!>
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
|
||||
*
|
||||
* SPEC VERSION: 0.1-152
|
||||
* PRIMARY LINKS: expressions, when-expression -> paragraph 5 -> sentence 1
|
||||
* expressions, when-expression, exhaustive-when-expressions -> paragraph 1 -> sentence 1
|
||||
* expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 9
|
||||
* expressions, when-expression -> paragraph 9 -> sentence 2
|
||||
* control--and-data-flow-analysis, performing-analysis-on-the-control-flow-graph, variable-initialization-analysis -> paragraph 2 -> sentence 1
|
||||
* control--and-data-flow-analysis, performing-analysis-on-the-control-flow-graph, variable-initialization-analysis -> paragraph 2 -> sentence 3
|
||||
*/
|
||||
|
||||
// Base for KT-6227
|
||||
enum class X { A, B, C, D }
|
||||
|
||||
fun foo(arg: X): String {
|
||||
var res = "XXX"
|
||||
when (arg) {
|
||||
X.A -> res = "A"
|
||||
X.B -> res = "B"
|
||||
}
|
||||
return res
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
|
||||
*
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ object Last : S()
|
||||
fun use(s: String) = s
|
||||
|
||||
fun foo(s: S) {
|
||||
when (s) {
|
||||
<!NON_EXHAUSTIVE_WHEN_STATEMENT!>when<!> (s) {
|
||||
First -> {}
|
||||
is Derived -> use(s.s)
|
||||
}
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
|
||||
*
|
||||
* SPEC VERSION: 0.1-152
|
||||
* PRIMARY LINKS: expressions, when-expression -> paragraph 5 -> sentence 1
|
||||
* expressions, when-expression, exhaustive-when-expressions -> paragraph 1 -> sentence 1
|
||||
* expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 9
|
||||
* expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 10
|
||||
* expressions, when-expression -> paragraph 9 -> sentence 2
|
||||
* control--and-data-flow-analysis, performing-analysis-on-the-control-flow-graph, variable-initialization-analysis -> paragraph 2 -> sentence 1
|
||||
* control--and-data-flow-analysis, performing-analysis-on-the-control-flow-graph, variable-initialization-analysis -> paragraph 2 -> sentence 3
|
||||
*/
|
||||
|
||||
// Base for KT-6227
|
||||
enum class X { A, B, C, D }
|
||||
|
||||
fun foo(arg: X?): String {
|
||||
var res = "XXX"
|
||||
// Should we report something here? Probably not, null is not an enum entry
|
||||
when (arg) {
|
||||
X.A -> res = "A"
|
||||
X.B -> res = "B"
|
||||
X.C -> res = "C"
|
||||
X.D -> res = "D"
|
||||
}
|
||||
return res
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
|
||||
*
|
||||
|
||||
-154
@@ -1,154 +0,0 @@
|
||||
// !LANGUAGE: -ProhibitNonExhaustiveWhenOnLogicalTypes
|
||||
|
||||
enum class SomeEnum {
|
||||
A, B
|
||||
}
|
||||
|
||||
sealed class Base {
|
||||
class A : Base()
|
||||
class B : Base()
|
||||
}
|
||||
|
||||
sealed interface IBase {
|
||||
interface A : IBase
|
||||
interface B : IBase
|
||||
}
|
||||
|
||||
// ------------------ not null ------------------
|
||||
|
||||
fun test_1(x: SomeEnum) {
|
||||
when (x) {
|
||||
SomeEnum.A -> ""
|
||||
}
|
||||
}
|
||||
|
||||
fun test_2(x: Base) {
|
||||
when (x) {
|
||||
is Base.A -> ""
|
||||
}
|
||||
}
|
||||
|
||||
fun test_3(x: IBase) {
|
||||
when (x) {
|
||||
is IBase.A -> ""
|
||||
}
|
||||
}
|
||||
|
||||
fun test_4(x: Boolean) {
|
||||
when (x) {
|
||||
true -> ""
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------ nullable ------------------
|
||||
|
||||
fun test_5(x: SomeEnum?) {
|
||||
when (x) {
|
||||
SomeEnum.A -> ""
|
||||
SomeEnum.B -> ""
|
||||
}
|
||||
|
||||
when (x) {
|
||||
SomeEnum.A -> ""
|
||||
null -> ""
|
||||
}
|
||||
}
|
||||
|
||||
fun test_6(x: Base?) {
|
||||
when (x) {
|
||||
is Base.A -> ""
|
||||
is Base.B -> ""
|
||||
}
|
||||
|
||||
when (x) {
|
||||
is Base.A -> ""
|
||||
null -> ""
|
||||
}
|
||||
}
|
||||
|
||||
fun test_7(x: IBase?) {
|
||||
when (x) {
|
||||
is IBase.A -> ""
|
||||
is IBase.B -> ""
|
||||
}
|
||||
when (x) {
|
||||
is IBase.A -> ""
|
||||
null -> ""
|
||||
}
|
||||
}
|
||||
|
||||
fun test_8(x: Boolean?) {
|
||||
when (x) {
|
||||
true -> ""
|
||||
false -> ""
|
||||
}
|
||||
|
||||
when (x) {
|
||||
true -> ""
|
||||
null -> ""
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------ with else ------------------
|
||||
|
||||
fun test_9(x: SomeEnum?) {
|
||||
when (x) {
|
||||
SomeEnum.A -> ""
|
||||
else -> ""
|
||||
}
|
||||
}
|
||||
|
||||
fun test_10(x: Base?) {
|
||||
when (x) {
|
||||
is Base.A -> ""
|
||||
else -> ""
|
||||
}
|
||||
}
|
||||
|
||||
fun test_11(x: IBase?) {
|
||||
when (x) {
|
||||
is IBase.A -> ""
|
||||
else -> ""
|
||||
}
|
||||
}
|
||||
|
||||
fun test_12(x: Boolean?) {
|
||||
when (x) {
|
||||
true -> ""
|
||||
else -> ""
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------ exhaustive ------------------
|
||||
|
||||
fun test_13(x: SomeEnum?) {
|
||||
when (x) {
|
||||
SomeEnum.A -> ""
|
||||
SomeEnum.B -> ""
|
||||
null -> ""
|
||||
}
|
||||
}
|
||||
|
||||
fun test_14(x: Base?) {
|
||||
when (x) {
|
||||
is Base.A -> ""
|
||||
is Base.B -> ""
|
||||
null -> ""
|
||||
}
|
||||
}
|
||||
|
||||
fun test_15(x: IBase?) {
|
||||
when (x) {
|
||||
is IBase.A -> ""
|
||||
is IBase.B -> ""
|
||||
null -> ""
|
||||
}
|
||||
}
|
||||
|
||||
fun test_16(x: Boolean?) {
|
||||
when (x) {
|
||||
true -> ""
|
||||
false -> ""
|
||||
null -> ""
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !LANGUAGE: -ProhibitNonExhaustiveWhenOnAlgebraicTypes
|
||||
|
||||
enum class SomeEnum {
|
||||
|
||||
-154
@@ -1,154 +0,0 @@
|
||||
// !LANGUAGE: +ProhibitNonExhaustiveWhenOnLogicalTypes
|
||||
|
||||
enum class SomeEnum {
|
||||
A, B
|
||||
}
|
||||
|
||||
sealed class Base {
|
||||
class A : Base()
|
||||
class B : Base()
|
||||
}
|
||||
|
||||
sealed interface IBase {
|
||||
interface A : IBase
|
||||
interface B : IBase
|
||||
}
|
||||
|
||||
// ------------------ not null ------------------
|
||||
|
||||
fun test_1(x: SomeEnum) {
|
||||
when (x) {
|
||||
SomeEnum.A -> ""
|
||||
}
|
||||
}
|
||||
|
||||
fun test_2(x: Base) {
|
||||
when (x) {
|
||||
is Base.A -> ""
|
||||
}
|
||||
}
|
||||
|
||||
fun test_3(x: IBase) {
|
||||
when (x) {
|
||||
is IBase.A -> ""
|
||||
}
|
||||
}
|
||||
|
||||
fun test_4(x: Boolean) {
|
||||
when (x) {
|
||||
true -> ""
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------ nullable ------------------
|
||||
|
||||
fun test_5(x: SomeEnum?) {
|
||||
when (x) {
|
||||
SomeEnum.A -> ""
|
||||
SomeEnum.B -> ""
|
||||
}
|
||||
|
||||
when (x) {
|
||||
SomeEnum.A -> ""
|
||||
null -> ""
|
||||
}
|
||||
}
|
||||
|
||||
fun test_6(x: Base?) {
|
||||
when (x) {
|
||||
is Base.A -> ""
|
||||
is Base.B -> ""
|
||||
}
|
||||
|
||||
when (x) {
|
||||
is Base.A -> ""
|
||||
null -> ""
|
||||
}
|
||||
}
|
||||
|
||||
fun test_7(x: IBase?) {
|
||||
when (x) {
|
||||
is IBase.A -> ""
|
||||
is IBase.B -> ""
|
||||
}
|
||||
when (x) {
|
||||
is IBase.A -> ""
|
||||
null -> ""
|
||||
}
|
||||
}
|
||||
|
||||
fun test_8(x: Boolean?) {
|
||||
when (x) {
|
||||
true -> ""
|
||||
false -> ""
|
||||
}
|
||||
|
||||
when (x) {
|
||||
true -> ""
|
||||
null -> ""
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------ with else ------------------
|
||||
|
||||
fun test_9(x: SomeEnum?) {
|
||||
when (x) {
|
||||
SomeEnum.A -> ""
|
||||
else -> ""
|
||||
}
|
||||
}
|
||||
|
||||
fun test_10(x: Base?) {
|
||||
when (x) {
|
||||
is Base.A -> ""
|
||||
else -> ""
|
||||
}
|
||||
}
|
||||
|
||||
fun test_11(x: IBase?) {
|
||||
when (x) {
|
||||
is IBase.A -> ""
|
||||
else -> ""
|
||||
}
|
||||
}
|
||||
|
||||
fun test_12(x: Boolean?) {
|
||||
when (x) {
|
||||
true -> ""
|
||||
else -> ""
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------ exhaustive ------------------
|
||||
|
||||
fun test_13(x: SomeEnum?) {
|
||||
when (x) {
|
||||
SomeEnum.A -> ""
|
||||
SomeEnum.B -> ""
|
||||
null -> ""
|
||||
}
|
||||
}
|
||||
|
||||
fun test_14(x: Base?) {
|
||||
when (x) {
|
||||
is Base.A -> ""
|
||||
is Base.B -> ""
|
||||
null -> ""
|
||||
}
|
||||
}
|
||||
|
||||
fun test_15(x: IBase?) {
|
||||
when (x) {
|
||||
is IBase.A -> ""
|
||||
is IBase.B -> ""
|
||||
null -> ""
|
||||
}
|
||||
}
|
||||
|
||||
fun test_16(x: Boolean?) {
|
||||
when (x) {
|
||||
true -> ""
|
||||
false -> ""
|
||||
null -> ""
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !LANGUAGE: +ProhibitNonExhaustiveWhenOnAlgebraicTypes
|
||||
|
||||
enum class SomeEnum {
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
fun test1() {
|
||||
if (true) {
|
||||
when (true) {
|
||||
true -> println()
|
||||
}
|
||||
} else {
|
||||
System.out?.println() // kotlin.Unit?
|
||||
}
|
||||
}
|
||||
|
||||
fun test2() {
|
||||
val mlist = arrayListOf("")
|
||||
if (true) {
|
||||
when (true) {
|
||||
true -> println()
|
||||
}
|
||||
} else {
|
||||
mlist.add("") // kotlin.Boolean
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
fun test1() {
|
||||
if (true) {
|
||||
<!NON_EXHAUSTIVE_WHEN_STATEMENT!>when<!> (true) {
|
||||
|
||||
Reference in New Issue
Block a user