[FIR] Implement checker for exhaustive when's in expression position
This commit is contained in:
@@ -12,7 +12,7 @@
|
||||
|
||||
enum class E { A, B }
|
||||
|
||||
fun test(e: E?) = when (e) {
|
||||
fun test(e: E?) = <!NO_ELSE_IN_WHEN!>when<!> (e) {
|
||||
E.A -> 1
|
||||
E.B -> 2
|
||||
}
|
||||
|
||||
+9
-9
@@ -1,18 +1,18 @@
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (POSITIVE)
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
|
||||
*
|
||||
* SPEC VERSION: 0.1-152
|
||||
* SPEC VERSION: 0.1-313
|
||||
* 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 3
|
||||
* expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 10
|
||||
* expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 4
|
||||
* expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 5
|
||||
*/
|
||||
|
||||
// See also: KT-3743
|
||||
fun foo(arg: Boolean?): String {
|
||||
// Must be NOT exhaustive
|
||||
return when(arg) {
|
||||
true -> "truth"
|
||||
false -> "falsehood"
|
||||
fun foo(arg: Boolean): String {
|
||||
// Must be exhaustive
|
||||
return <!NO_ELSE_IN_WHEN!>when<!>(arg) {
|
||||
2 == 2 -> "truth"
|
||||
2 == 1 -> "falsehood"
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
// FIR_IDENTICAL
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
|
||||
*
|
||||
|
||||
@@ -12,7 +12,7 @@ enum class MyEnum {
|
||||
}
|
||||
|
||||
fun foo(x: MyEnum): Int {
|
||||
return when (x) {
|
||||
return <!NO_ELSE_IN_WHEN!>when<!> (x) {
|
||||
is <!UNRESOLVED_REFERENCE!>MyEnum.A<!> -> 1
|
||||
is <!UNRESOLVED_REFERENCE!>MyEnum.B<!> -> 2
|
||||
is <!UNRESOLVED_REFERENCE!>MyEnum.C<!> -> 3
|
||||
|
||||
@@ -13,7 +13,7 @@ enum class MyEnum {
|
||||
}
|
||||
|
||||
fun foo(x: MyEnum): Int {
|
||||
return when (x) {
|
||||
return <!NO_ELSE_IN_WHEN!>when<!> (x) {
|
||||
MyEnum.A -> 1
|
||||
is <!UNRESOLVED_REFERENCE!>MyEnum.B<!> -> 2
|
||||
is <!UNRESOLVED_REFERENCE!>MyEnum.C<!> -> 3
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
|
||||
*
|
||||
* SPEC VERSION: 0.1-152
|
||||
* PRIMARY LINKS: expressions, when-expression -> paragraph 5 -> sentence 1
|
||||
* expressions, when-expression -> paragraph 9 -> sentence 2
|
||||
* expressions, when-expression, exhaustive-when-expressions -> paragraph 1 -> sentence 1
|
||||
*/
|
||||
|
||||
fun foo(x: Int) {
|
||||
val y: Unit = when (x) {
|
||||
2 -> {}
|
||||
3 -> {}
|
||||
}
|
||||
return y
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
|
||||
*
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
|
||||
*
|
||||
* SPEC VERSION: 0.1-152
|
||||
* PRIMARY LINKS: expressions, when-expression -> paragraph 5 -> sentence 1
|
||||
* expressions, when-expression -> paragraph 9 -> sentence 2
|
||||
* expressions, when-expression, exhaustive-when-expressions -> paragraph 1 -> sentence 1
|
||||
*/
|
||||
|
||||
fun foo(x: Int): Any {
|
||||
val v = when (x) {
|
||||
2 -> 0
|
||||
}
|
||||
return v
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
|
||||
*
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
|
||||
*
|
||||
* SPEC VERSION: 0.1-152
|
||||
* PRIMARY LINKS: expressions, when-expression -> paragraph 5 -> sentence 1
|
||||
* expressions, when-expression -> paragraph 9 -> sentence 2
|
||||
* expressions, when-expression, exhaustive-when-expressions -> paragraph 1 -> sentence 1
|
||||
*/
|
||||
|
||||
fun foo(x: Int): Any {
|
||||
return when (x) {
|
||||
2 -> 0
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
|
||||
*
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
|
||||
*
|
||||
* SPEC VERSION: 0.1-152
|
||||
* PRIMARY LINKS: expressions, when-expression -> paragraph 5 -> sentence 1
|
||||
* expressions, when-expression -> paragraph 9 -> sentence 2
|
||||
* expressions, when-expression, exhaustive-when-expressions -> paragraph 1 -> sentence 1
|
||||
*/
|
||||
|
||||
|
||||
fun foo(x: Int) {
|
||||
return when (x) {
|
||||
2 -> {}
|
||||
3 -> {}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
|
||||
*
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (POSITIVE)
|
||||
*
|
||||
|
||||
@@ -1,29 +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
|
||||
*/
|
||||
|
||||
// See KT-6399: exhaustive whens on platform enums
|
||||
|
||||
// FILE: J.java
|
||||
|
||||
public enum J {
|
||||
A, B;
|
||||
|
||||
public static J create() {
|
||||
return J.A;
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: K.kt
|
||||
|
||||
fun foo(): Int {
|
||||
// When is not-exhaustive
|
||||
return when (J.create()) {
|
||||
J.A -> 1
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
|
||||
*
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@
|
||||
enum class X { A, B }
|
||||
fun foo(arg: X?): Int {
|
||||
if (arg != null) {
|
||||
return when (arg) {
|
||||
return <!NO_ELSE_IN_WHEN!>when<!> (arg) {
|
||||
X.B -> 2
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
|
||||
*
|
||||
* SPEC VERSION: 0.1-152
|
||||
* PRIMARY LINKS: expressions, when-expression -> paragraph 5 -> sentence 1
|
||||
* expressions, when-expression -> paragraph 6 -> sentence 1
|
||||
* expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 6
|
||||
* expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 7
|
||||
* expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 8
|
||||
*/
|
||||
|
||||
sealed class A {
|
||||
class B: A() {
|
||||
class C: A()
|
||||
}
|
||||
}
|
||||
|
||||
class D: A()
|
||||
|
||||
fun test(a: A) {
|
||||
val nonExhaustive = when (a) {
|
||||
is A.B -> "B"
|
||||
is A.B.C -> "C"
|
||||
}
|
||||
|
||||
val exhaustive = when (a) {
|
||||
is A.B -> "B"
|
||||
is A.B.C -> "C"
|
||||
is D -> "D"
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ fun foo(): Int {
|
||||
fun bar(): Int {
|
||||
val a = "a"
|
||||
if (a.length > 0) {
|
||||
return when (a) {
|
||||
return <!NO_ELSE_IN_WHEN!>when<!> (a) {
|
||||
"a" -> 1
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -38,4 +38,4 @@ fun test4() {
|
||||
2 -> bar(x, y)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
// !LANGUAGE: +VariableDeclarationInWhenSubject
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||
|
||||
enum class E { FIRST, SECOND }
|
||||
|
||||
fun testSmartcastToEnumInSubjectInitializer1(e: E?) {
|
||||
val x1 = when (val ne = e!!) {
|
||||
E.FIRST -> "f"
|
||||
E.SECOND -> "s"
|
||||
}
|
||||
}
|
||||
|
||||
fun testSmartcastToEnumInSubjectInitializer2(e: E?) {
|
||||
val x2 = when (val ne: Any = e!!) { // NB explicit type annotation
|
||||
E.FIRST -> "f"
|
||||
E.SECOND -> "s"
|
||||
}
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !LANGUAGE: +VariableDeclarationInWhenSubject
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||
|
||||
|
||||
-20
@@ -1,20 +0,0 @@
|
||||
// !LANGUAGE: +VariableDeclarationInWhenSubject
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||
|
||||
sealed class Either
|
||||
class Left : Either()
|
||||
class Right : Either()
|
||||
|
||||
fun testSmartcastToSealedInSubjectInitializer1(x: Any?) {
|
||||
val y1 = when (val either = x as Either) {
|
||||
is Left -> "L"
|
||||
is Right -> "R"
|
||||
}
|
||||
}
|
||||
|
||||
fun testSmartcastToSealedInSubjectInitializer2(x: Any?) {
|
||||
val y2 = when (val either: Any = x as Either) { // NB explicit type annotation
|
||||
is Left -> "L"
|
||||
is Right -> "R"
|
||||
}
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !LANGUAGE: +VariableDeclarationInWhenSubject
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||
|
||||
|
||||
Reference in New Issue
Block a user