From 06bae1e52fcd7e0abd6094eb638cc3b9d7d0035a Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Wed, 15 Apr 2020 13:07:41 +0300 Subject: [PATCH] FIR: Adjust testData for spec tests: when-expression --- .../p-2/neg/1.1.fir.kt | 25 ++ .../p-2/neg/1.2.fir.kt | 26 ++ .../p-2/neg/10.1.fir.kt | 27 ++ .../p-2/neg/10.2.fir.kt | 81 +++++ .../p-2/neg/10.3.fir.kt | 46 +++ .../p-2/neg/3.1.fir.kt | 45 +++ .../p-2/neg/6.1.fir.kt | 83 +++++ .../p-2/pos/1.3.fir.kt | 75 ++++ .../p-2/pos/10.2.fir.kt | 35 ++ .../p-2/pos/10.3.fir.kt | 75 ++++ .../p-2/pos/6.1.fir.kt | 85 +++++ .../when-expression/p-1/pos/3.1.fir.kt | 15 + .../when-expression/p-2/neg/2.1.fir.kt | 25 ++ .../when-expression/p-2/neg/2.2.fir.kt | 22 ++ .../when-expression/p-2/pos/1.1.fir.kt | 323 +++++++++++++++++ .../when-expression/p-2/pos/1.2.fir.kt | 32 ++ .../when-expression/p-2/pos/2.1.fir.kt | 122 +++++++ .../when-expression/p-2/pos/2.3.fir.kt | 97 ++++++ .../when-expression/p-3/neg/2.1.fir.kt | 54 +++ .../when-expression/p-4/neg/1.1.fir.kt | 69 ++++ .../when-expression/p-4/pos/1.1.fir.kt | 114 ++++++ .../when-expression/p-5/pos/1.1.fir.kt | 326 ++++++++++++++++++ .../when-expression/p-5/pos/1.2.fir.kt | 34 ++ .../when-expression/p-6/neg/1.1.fir.kt | 38 ++ .../when-expression/p-6/neg/1.2.fir.kt | 20 ++ .../when-expression/p-6/neg/11.1.fir.kt | 35 ++ .../when-expression/p-6/neg/12.1.fir.kt | 33 ++ .../when-expression/p-6/neg/3.1.fir.kt | 21 ++ .../when-expression/p-6/neg/3.2.fir.kt | 36 ++ .../when-expression/p-6/neg/7.1.fir.kt | 34 ++ .../when-expression/p-6/pos/1.1.fir.kt | 69 ++++ .../when-expression/p-6/pos/1.2.fir.kt | 58 ++++ .../when-expression/p-6/pos/1.4.fir.kt | 59 ++++ .../when-expression/p-6/pos/10.1.fir.kt | 286 +++++++++++++++ .../when-expression/p-6/pos/10.2.fir.kt | 263 ++++++++++++++ .../when-expression/p-6/pos/11.1.fir.kt | 32 ++ 36 files changed, 2820 insertions(+) create mode 100644 compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/1.1.fir.kt create mode 100644 compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/1.2.fir.kt create mode 100644 compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/10.1.fir.kt create mode 100644 compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/10.2.fir.kt create mode 100644 compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/10.3.fir.kt create mode 100644 compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/3.1.fir.kt create mode 100644 compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/6.1.fir.kt create mode 100644 compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/pos/1.3.fir.kt create mode 100644 compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/pos/10.2.fir.kt create mode 100644 compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/pos/10.3.fir.kt create mode 100644 compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/pos/6.1.fir.kt create mode 100644 compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-1/pos/3.1.fir.kt create mode 100644 compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-2/neg/2.1.fir.kt create mode 100644 compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-2/neg/2.2.fir.kt create mode 100644 compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-2/pos/1.1.fir.kt create mode 100644 compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-2/pos/1.2.fir.kt create mode 100644 compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-2/pos/2.1.fir.kt create mode 100644 compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-2/pos/2.3.fir.kt create mode 100644 compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-3/neg/2.1.fir.kt create mode 100644 compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-4/neg/1.1.fir.kt create mode 100644 compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-4/pos/1.1.fir.kt create mode 100644 compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-5/pos/1.1.fir.kt create mode 100644 compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-5/pos/1.2.fir.kt create mode 100644 compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/neg/1.1.fir.kt create mode 100644 compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/neg/1.2.fir.kt create mode 100644 compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/neg/11.1.fir.kt create mode 100644 compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/neg/12.1.fir.kt create mode 100644 compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/neg/3.1.fir.kt create mode 100644 compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/neg/3.2.fir.kt create mode 100644 compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/neg/7.1.fir.kt create mode 100644 compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/1.1.fir.kt create mode 100644 compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/1.2.fir.kt create mode 100644 compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/1.4.fir.kt create mode 100644 compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/10.1.fir.kt create mode 100644 compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/10.2.fir.kt create mode 100644 compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/11.1.fir.kt diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/1.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/1.1.fir.kt new file mode 100644 index 00000000000..743ae6b5ecb --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/1.1.fir.kt @@ -0,0 +1,25 @@ +// SKIP_TXT + +/* + * KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE) + * + * SPEC VERSION: 0.1-100 + * PLACE: expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 1 + * NUMBER: 1 + * DESCRIPTION: Non-exhaustive when, without bound value, without else branch. + */ + +// TESTCASE NUMBER: 1 +fun case_1(value_1: Int): String = when { + value_1 == 1 -> "" + value_1 == 2 -> "" + value_1 == 3 -> "" +} + +// TESTCASE NUMBER: 2 +fun case_2(value_1: Int): String = when { + value_1 == 1 -> "" +} + +// TESTCASE NUMBER: 3 +fun case_3(): Int = when {} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/1.2.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/1.2.fir.kt new file mode 100644 index 00000000000..69821c25095 --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/1.2.fir.kt @@ -0,0 +1,26 @@ +// !DIAGNOSTICS: -UNUSED_EXPRESSION +// SKIP_TXT + +/* + * KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE) + * + * SPEC VERSION: 0.1-100 + * PLACE: expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 1 + * NUMBER: 2 + * DESCRIPTION: Non-exhaustive when, with bound value, without else branch. + */ + +// TESTCASE NUMBER: 1 +fun case_1(value_1: Int): String = when (value_1) { + 1 -> "" + 2 -> "" + 3 -> "" +} + +// TESTCASE NUMBER: 2 +fun case_2(value_1: Int): String = when (value_1) { + 1 -> "" +} + +// TESTCASE NUMBER: 3 +fun case_3(value_1: Int): Int = when (value_1) {} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/10.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/10.1.fir.kt new file mode 100644 index 00000000000..adc3a72c8a6 --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/10.1.fir.kt @@ -0,0 +1,27 @@ +// !DIAGNOSTICS: -UNUSED_EXPRESSION +// SKIP_TXT + +/* + * KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE) + * + * SPEC VERSION: 0.1-100 + * PLACE: expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 10 + * NUMBER: 1 + * DESCRIPTION: Non-exhaustive when using nullable boolean values. + */ + + +// TESTCASE NUMBER: 1 +fun case_1(value_1: Boolean?): String = when(value_1) { + true -> "" + false -> "" +} + +// TESTCASE NUMBER: 2 +fun case_2(value_1: Boolean?): String = when(value_1) { + true -> "" + null -> "" +} + +// TESTCASE NUMBER: 3 +fun case_3(value_1: Boolean?): Int = when(value_1) { } diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/10.2.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/10.2.fir.kt new file mode 100644 index 00000000000..9ceef86b917 --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/10.2.fir.kt @@ -0,0 +1,81 @@ +// !DIAGNOSTICS: -UNUSED_EXPRESSION +// SKIP_TXT + +/* + * KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE) + * + * SPEC VERSION: 0.1-100 + * PLACE: expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 10 + * NUMBER: 2 + * DESCRIPTION: Non-exhaustive when using subclasses of the nullable sealed class. + * HELPERS: sealedClasses + */ + +// TESTCASE NUMBER: 1 +fun case_1(value_1: SealedClass?): String = when(value_1) { + is SealedChild1 -> "" + is SealedChild2 -> "" + is SealedChild3 -> "" +} + +// TESTCASE NUMBER: 2 +fun case_2(value_1: SealedClassMixed?): String = when(value_1) { + is SealedMixedChild1 -> "" + is SealedMixedChild2 -> "" + SealedMixedChildObject1 -> "" + null -> "" +} + +// TESTCASE NUMBER: 3 +fun case_3(value_1: SealedClassMixed?): String = when(value_1) { + null, is SealedMixedChild1, is SealedMixedChild2, SealedMixedChildObject1 -> "" +} + +// TESTCASE NUMBER: 4 +fun case_4(value_1: SealedClassMixed?): String = when(value_1) { + is SealedMixedChild1 -> "" + is SealedMixedChild2 -> "" + is SealedMixedChild3 -> "" + SealedMixedChildObject1 -> "" + SealedMixedChildObject2 -> "" + SealedMixedChildObject3 -> "" +} + +// TESTCASE NUMBER: 5 +fun case_5(value_1: SealedClassMixed?): String = when(value_1) { + is SealedMixedChild1 -> "" + is SealedMixedChild2 -> "" + is SealedMixedChild3 -> "" +} + +// TESTCASE NUMBER: 6 +fun case_6(value_1: SealedClassMixed?): Int = when(value_1) {} + +// TESTCASE NUMBER: 7 +fun case_7(value_1: SealedClassMixed?): String = when(value_1) { + is SealedMixedChild1 -> "" + is SealedMixedChild2-> "" + is SealedMixedChild3 -> "" + null -> "" +} + +// TESTCASE NUMBER: 8 +fun case_8(value_1: SealedClassMixed?): String = when(value_1) { + SealedMixedChildObject1 -> "" +} + +/* + * TESTCASE NUMBER: 9 + * DISCUSSION: maybe make exhaustive without else? + */ +fun case_9(value_1: Any?): String = when (value_1) { + is Any -> "" + null -> "" +} + +/* + * TESTCASE NUMBER: 10 + * DISCUSSION + * ISSUES: KT-26044 + */ +fun case_10(value: SealedClassEmpty): String = when (value) {} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/10.3.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/10.3.fir.kt new file mode 100644 index 00000000000..6a23db1904d --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/10.3.fir.kt @@ -0,0 +1,46 @@ +// !DIAGNOSTICS: -UNUSED_EXPRESSION +// SKIP_TXT + +/* + * KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE) + * + * SPEC VERSION: 0.1-100 + * PLACE: expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 10 + * NUMBER: 3 + * DESCRIPTION: Non-exhaustive when using nullable enum values. + * HELPERS: enumClasses + */ + +// TESTCASE NUMBER: 1 +fun case_1(value_1: EnumClass?): String = when(value_1) { + EnumClass.EAST -> "" + EnumClass.SOUTH -> "" + EnumClass.NORTH -> "" + EnumClass.WEST -> "" +} + +// TESTCASE NUMBER: 2 +fun case_2(value_1: EnumClass?): String = when(value_1) { + EnumClass.EAST -> "" + EnumClass.SOUTH -> "" + EnumClass.NORTH -> "" + null -> "" +} + +// TESTCASE NUMBER: 3 +fun case_3(value_1: EnumClass?): String = when(value_1) { + EnumClass.EAST, null, EnumClass.SOUTH, EnumClass.NORTH -> "" +} + +// TESTCASE NUMBER: 4 +fun case_4(value_1: EnumClassSingle): Int = when(value_1) {} + +// TESTCASE NUMBER: 5 +fun case_5(value_1: EnumClassSingle?): String = when(value_1) { + EnumClassSingle.EVERYTHING -> "" +} + +// TESTCASE NUMBER: 6 +fun case_6(value_1: EnumClassSingle?): String = when(value_1) { + null -> "" +} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/3.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/3.1.fir.kt new file mode 100644 index 00000000000..9e48dd51309 --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/3.1.fir.kt @@ -0,0 +1,45 @@ +// !DIAGNOSTICS: -UNUSED_EXPRESSION +// SKIP_TXT + +/* + * KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE) + * + * SPEC VERSION: 0.1-100 + * PLACE: expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 3 + * NUMBER: 1 + * DESCRIPTION: Non-exhaustive when using boolean values. + */ + +// TESTCASE NUMBER: 1 +fun case_1(value_1: Boolean): String = when(value_1) { + true -> "" +} + +// TESTCASE NUMBER: 2 +fun case_2(value_1: Boolean): String = when(value_1) { + false -> "" +} + +// TESTCASE NUMBER: 3 +fun case_3(value_1: Boolean): Int = when(value_1) { } + +// TESTCASE NUMBER: 4 +fun case_4(value_1: Boolean): String = when { + value_1 == true -> "" + value_1 == false -> "" +} + +/* + * TESTCASE NUMBER: 5 + * DISCUSSION: maybe use const propagation here? + * ISSUES: KT-25265 + */ +fun case_5(value_1: Boolean): String { + val trueValue = true + val falseValue = false + + return when (value_1) { + trueValue -> "" + falseValue -> "" + } +} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/6.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/6.1.fir.kt new file mode 100644 index 00000000000..0cb4e8c5de8 --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/6.1.fir.kt @@ -0,0 +1,83 @@ +// !DIAGNOSTICS: -UNUSED_EXPRESSION +// SKIP_TXT + +/* + * KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE) + * + * SPEC VERSION: 0.1-100 + * PLACE: expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 6 + * NUMBER: 1 + * DESCRIPTION: Non-exhaustive when using subclasses of the sealed class. + * HELPERS: sealedClasses + */ + +// TESTCASE NUMBER: 1 +fun case_1(value_1: SealedClass): String = when(value_1) { + is SealedChild1 -> "" + is SealedChild2 -> "" +} + +// TESTCASE NUMBER: 2 +fun case_2(value_1: SealedClass): String = when(value_1) { + is SealedChild1, is SealedChild2 -> "" +} + +// TESTCASE NUMBER: 3 +fun case_3(value_1: SealedClassMixed): String = when(value_1) { + is SealedMixedChild1 -> "" + is SealedMixedChild2 -> "" + SealedMixedChildObject1 -> "" +} + +// TESTCASE NUMBER: 4 +fun case_4(value_1: SealedClassMixed): String = when(value_1) { + SealedMixedChildObject1, is SealedMixedChild2, is SealedMixedChild1 -> "" +} + +// TESTCASE NUMBER: 5 +fun case_5(value_1: SealedClassMixed): String = when(value_1) { + is SealedMixedChild1 -> "" + is SealedMixedChild2 -> "" + is SealedMixedChild3 -> "" +} + +// TESTCASE NUMBER: 6 +fun case_6(value_1: SealedClassMixed): Int = when(value_1) { } + +// TESTCASE NUMBER: 7 +fun case_7(value_1: SealedClassSingleWithObject): Int = when(value_1) { } + +// TESTCASE NUMBER: 8 +fun case_8(value_1: SealedClassEmpty): String = when (value_1) { } + +// TESTCASE NUMBER: 9 +fun case_9(value_1: Number): String = when (value_1) { + is Byte -> "" + is Double -> "" + is Float -> "" + is Int -> "" + is Long -> "" + is Short -> "" +} + +/* + * TESTCASE NUMBER: 10 + * DISCUSSION: maybe make exhaustive without else? + */ +fun case_10(value_1: Any): String = when (value_1) { + is Any -> "" +} + +// TESTCASE NUMBER: 11 +fun case_11(value_1: SealedClass): String = when { + value_1 is SealedChild1 -> "" + value_1 is SealedChild2 -> "" + value_1 is SealedChild3 -> "" +} + +// TESTCASE NUMBER: 12 +fun case_12(value_1: SealedClassMixed): String = when(value_1) { + is SealedMixedChild1 -> "" + is SealedMixedChild2 -> "" + is SealedMixedChild3 -> "" +} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/pos/1.3.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/pos/1.3.fir.kt new file mode 100644 index 00000000000..745a7145b57 --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/pos/1.3.fir.kt @@ -0,0 +1,75 @@ +// SKIP_TXT + +/* + * KOTLIN DIAGNOSTICS SPEC TEST (POSITIVE) + * + * SPEC VERSION: 0.1-100 + * PLACE: expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 1 + * NUMBER: 3 + * DESCRIPTION: Exhaustive when, with bound value (sealed, enum, boolean), with redundant else branch. + * HELPERS: enumClasses, sealedClasses + */ + +// TESTCASE NUMBER: 1 +fun case_1(value_1: EnumClass): String = when (value_1) { + EnumClass.EAST -> "" + EnumClass.NORTH -> "" + EnumClass.SOUTH -> "" + EnumClass.WEST -> "" + else -> "" +} + +// TESTCASE NUMBER: 2 +fun case_2(value_1: EnumClass?): String = when (value_1) { + EnumClass.EAST -> "" + EnumClass.NORTH -> "" + EnumClass.SOUTH -> "" + EnumClass.WEST -> "" + null -> "" + else -> "" +} + +// TESTCASE NUMBER: 3 +fun case_3(value_1: Boolean): String = when (value_1) { + true -> "" + false -> "" + else -> "" +} + +// TESTCASE NUMBER: 4 +fun case_4(value_1: Boolean?): String = when (value_1) { + true -> "" + false -> "" + null -> "" + else -> "" +} + +// TESTCASE NUMBER: 5 +fun case_5(value_1: SealedClass): String = when (value_1) { + is SealedChild1 -> "" + is SealedChild2 -> "" + is SealedChild3 -> "" + else -> "" +} + +// TESTCASE NUMBER: 6 +fun case_6(value_1: SealedClass?): String = when (value_1) { + is SealedChild1 -> "" + is SealedChild2 -> "" + is SealedChild3 -> "" + null -> "" + else -> "" +} + +// TESTCASE NUMBER: 7 +fun case_7(value_1: SealedClassSingle): String = when (value_1) { + is SealedClassSingle -> "" + else -> "" +} + +// TESTCASE NUMBER: 8 +fun case_8(value_1: SealedClassSingle?): String = when (value_1) { + is SealedClassSingle -> "" + null -> "" + else -> "" +} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/pos/10.2.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/pos/10.2.fir.kt new file mode 100644 index 00000000000..8994fc26f28 --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/pos/10.2.fir.kt @@ -0,0 +1,35 @@ +// SKIP_TXT + +/* + * KOTLIN DIAGNOSTICS SPEC TEST (POSITIVE) + * + * SPEC VERSION: 0.1-100 + * PLACE: expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 10 + * NUMBER: 2 + * DESCRIPTION: Exhaustive when using nullable enum values. + * HELPERS: enumClasses + */ + +// TESTCASE NUMBER: 1 +fun case_1(value_1: EnumClass?): String = when (value_1) { + EnumClass.EAST -> "" + EnumClass.NORTH -> "" + EnumClass.SOUTH -> "" + EnumClass.WEST -> "" + null -> "" +} + +// TESTCASE NUMBER: 2 +fun case_2(value_1: EnumClassSingle?): String = when (value_1) { + EnumClassSingle.EVERYTHING -> "" + null -> "" +} + +/* + * TESTCASE NUMBER: 3 + * UNEXPECTED BEHAVIOUR + * ISSUES: KT-26044 + */ +fun case_3(value_1: EnumClassEmpty?): String = when(value_1) { + null -> "" +} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/pos/10.3.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/pos/10.3.fir.kt new file mode 100644 index 00000000000..fda8fb8fa9f --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/pos/10.3.fir.kt @@ -0,0 +1,75 @@ +// SKIP_TXT + +/* + * KOTLIN DIAGNOSTICS SPEC TEST (POSITIVE) + * + * SPEC VERSION: 0.1-100 + * PLACE: expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 10 + * NUMBER: 3 + * DESCRIPTION: Exhaustive when using subclasses of the nullable sealed class. + * HELPERS: sealedClasses + */ + +// TESTCASE NUMBER: 1 +fun case_1(value_1: SealedClass?): Int = when (value_1) { + is SealedChild1 -> value_1.number + is SealedChild2 -> value_1.e1 + value_1.e2 + is SealedChild3 -> value_1.m1 + value_1.m2 + null -> 0 +} + +// TESTCASE NUMBER: 2 +fun case_2(value_1: SealedClass?): String = when (value_1) { + is SealedClass -> "" + null -> "" +} + +// TESTCASE NUMBER: 3 +fun case_3(value_1: SealedClassWithMethods?): String = when (value_1) { + is SealedWithMethodsChild1 -> value_1.m1() + is SealedWithMethodsChild2 -> value_1.m2() + is SealedWithMethodsChild3 -> value_1.m3() + null -> "" +} + +// TESTCASE NUMBER: 4 +fun case_4(value_1: SealedClassWithObjects?): String = when (value_1) { + SealedWithObjectsChild1 -> "" + SealedWithObjectsChild2 -> "" + SealedWithObjectsChild3 -> "" + null -> "" +} + +// TESTCASE NUMBER: 5 +fun case_5(value_1: SealedClassMixed?): String = when (value_1) { + is SealedMixedChild1 -> "" + is SealedMixedChild2 -> "" + is SealedMixedChild3 -> "" + SealedMixedChildObject1 -> "" + SealedMixedChildObject2 -> "" + SealedMixedChildObject3 -> "" + null -> "" +} + +/* + * TESTCASE NUMBER: 6 + * DISCUSSION: is it correct that objects can be checked using the type checking operator? + */ +fun case_6(value_1: SealedClassMixed?): String = when (value_1) { + is SealedMixedChild1 -> "" + is SealedMixedChild2 -> "" + is SealedMixedChild3 -> "" + is SealedMixedChildObject1 -> "" + is SealedMixedChildObject2 -> "" + is SealedMixedChildObject3 -> "" + null -> "" +} + +/* + * TESTCASE NUMBER: 7 + * UNEXPECTED BEHAVIOUR: must be exhaustive + * ISSUES: KT-26044 + */ +fun case_7(value: SealedClassEmpty?): String = when (value) { + null -> "" +} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/pos/6.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/pos/6.1.fir.kt new file mode 100644 index 00000000000..ef8e28806ab --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/pos/6.1.fir.kt @@ -0,0 +1,85 @@ +// !DIAGNOSTICS: -UNUSED_EXPRESSION +// SKIP_TXT + +/* + * KOTLIN DIAGNOSTICS SPEC TEST (POSITIVE) + * + * SPEC VERSION: 0.1-100 + * PLACE: expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 6 + * NUMBER: 1 + * DESCRIPTION: Exhaustive when using subclasses of the sealed class. + * HELPERS: sealedClasses + */ + +// TESTCASE NUMBER: 1 +fun case_1(value_1: SealedClass): Int = when (value_1) { + is SealedChild1 -> value_1.number + is SealedChild2 -> value_1.e1 + value_1.e2 + is SealedChild3 -> value_1.m1 + value_1.m2 +} + +// TESTCASE NUMBER: 2 +fun case_2(value_1: SealedClass): String = when (value_1) { + is SealedClass -> "" +} + +// TESTCASE NUMBER: 3 +fun case_3(value_1: SealedClassWithMethods): String = when (value_1) { + is SealedWithMethodsChild1 -> value_1.m1() + is SealedWithMethodsChild2 -> value_1.m2() + is SealedWithMethodsChild3 -> value_1.m3() +} + +// TESTCASE NUMBER: 4 +fun case_4(value_1: SealedClassWithObjects): String = when (value_1) { + SealedWithObjectsChild1 -> "" + SealedWithObjectsChild2 -> "" + SealedWithObjectsChild3 -> "" +} + +// TESTCASE NUMBER: 5 +fun case_5(value_1: SealedClassMixed): String = when (value_1) { + is SealedMixedChild1 -> "" + is SealedMixedChild2 -> "" + is SealedMixedChild3 -> "" + SealedMixedChildObject1 -> "" + SealedMixedChildObject2 -> "" + SealedMixedChildObject3 -> "" +} + +/* + * TESTCASE NUMBER: 6 + * DISCUSSION: is it correct that objects can be checked using the type checking operator? + */ +fun case_6(value_1: SealedClassMixed): String = when (value_1) { + is SealedMixedChild1 -> "" + is SealedMixedChild2 -> "" + is SealedMixedChild3 -> "" + is SealedMixedChildObject1 -> "" + is SealedMixedChildObject2 -> "" + is SealedMixedChildObject3 -> "" +} + +// TESTCASE NUMBER: 7 +fun case_7(value_1: SealedClassEmpty): String = when (value_1) { + else -> "" +} + +/* + * TESTCASE NUMBER: 8 + * UNEXPECTED BEHAVIOUR: must be exhaustive + * ISSUES: KT-22996 + */ +fun case_8(value: SealedClass?): String = when (value) { + is SealedChild1, !is SealedChild3?, is SealedChild3? -> "" +} + +/* + * TESTCASE NUMBER: 9 + * UNEXPECTED BEHAVIOUR: must be exhaustive + * ISSUES: KT-22996 + */ +fun case_9(value: SealedClass?): String = when (value) { + is SealedChild1, !is SealedChild3 -> "" + is SealedChild3? -> "" +} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-1/pos/3.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-1/pos/3.1.fir.kt new file mode 100644 index 00000000000..36cb347f999 --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-1/pos/3.1.fir.kt @@ -0,0 +1,15 @@ +// SKIP_TXT + +/* + * KOTLIN DIAGNOSTICS SPEC TEST (POSITIVE) + * + * SPEC VERSION: 0.1-100 + * PLACE: expressions, when-expression -> paragraph 1 -> sentence 3 + * NUMBER: 1 + * DESCRIPTION: Empty when with bound value. + */ + +// TESTCASE NUMBER: 1 +fun case_1(value_1: Int) { + when (value_1) {} +} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-2/neg/2.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-2/neg/2.1.fir.kt new file mode 100644 index 00000000000..7de1a624ad9 --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-2/neg/2.1.fir.kt @@ -0,0 +1,25 @@ +// SKIP_TXT + +/* + * KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE) + * + * SPEC VERSION: 0.1-100 + * PLACE: expressions, when-expression -> paragraph 2 -> sentence 2 + * NUMBER: 1 + * DESCRIPTION: When with non-boolean value in the when condition. + * HELPERS: typesProvider + */ + +// TESTCASE NUMBER: 1 +fun case_1(value_1: Int, value_2: String, value_3: TypesProvider): String { + when { + .012f / value_1 -> return "" + "$value_2..." -> return "" + '-' -> return "" + {} -> return "" + value_3.getAny() -> return "" + -10..-1 -> return "" + } + + return "" +} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-2/neg/2.2.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-2/neg/2.2.fir.kt new file mode 100644 index 00000000000..927de327d6b --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-2/neg/2.2.fir.kt @@ -0,0 +1,22 @@ +// SKIP_TXT + +/* + * KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE) + * + * SPEC VERSION: 0.1-100 + * PLACE: expressions, when-expression -> paragraph 2 -> sentence 2 + * NUMBER: 2 + * DESCRIPTION: When without bound value, forbidden comma in the when condition. + * HELPERS: typesProvider, classes + */ + +// TESTCASE NUMBER: 1 +fun case_1(value_1: TypesProvider) { + when { + getBoolean(), value_1.getBoolean() -> return + value_1.getBoolean() && getBoolean(), getLong() == 1000L -> return + Out(), getLong(), {}, Any(), throw Exception() -> return + } + + return +} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-2/pos/1.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-2/pos/1.1.fir.kt new file mode 100644 index 00000000000..e9e07e0684e --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-2/pos/1.1.fir.kt @@ -0,0 +1,323 @@ +// !DIAGNOSTICS: -UNUSED_EXPRESSION -DEBUG_INFO_SMARTCAST +// SKIP_TXT + +/* + * KOTLIN DIAGNOSTICS SPEC TEST (POSITIVE) + * + * SPEC VERSION: 0.1-100 + * PLACE: expressions, when-expression -> paragraph 2 -> sentence 1 + * NUMBER: 1 + * DESCRIPTION: When without bound value, various expressions in the control structure body. + * HELPERS: typesProvider, classes, functions + */ + +// TESTCASE NUMBER: 1 +fun case_1(value_1: Int) { + when { + value_1 == 1 -> true + value_1 == 2 -> 100 + value_1 == 3 -> -.09f + value_1 == 4 -> '.' + value_1 == 5 -> "..." + value_1 == 6 -> null + } +} + +// TESTCASE NUMBER: 2 +fun case_2(value_1: Int, value_2: Byte, value_3: TypesProvider) { + when { + value_1 == 1 -> -.09 % 10L + value_1 == 3 -> value_2 / -5 + value_1 == 2 -> value_3.getChar() - 11 + 90 + } +} + +// TESTCASE NUMBER: 3 +fun case_3(value_1: Int, value_2: Boolean, value_3: Long) { + when { + value_1 == 1 -> value_2 + value_1 == 2 -> !value_2 + value_1 == 3 -> getBoolean() && value_2 + value_1 == 5 -> getChar() != 'a' + value_1 == 6 -> Out() === getAny() + value_1 == 7 -> value_3 <= 11 + } +} + +// TESTCASE NUMBER: 4 +fun case_4(value_1: Int, value_2: String, value_3: String) { + when { + value_1 == 1 -> "..." + value_2 + "" + "$value_3" + "..." + value_1 == 2 -> value_2 + getString() + } +} + +// TESTCASE NUMBER: 5 +fun case_5(value_1: Int, value_2: Int, value_3: Boolean?) { + when { + value_1 == 1 -> when { + value_2 > 1000 -> "1" + value_2 > 100 -> "2" + else -> "3" + } + value_1 == 2 -> when { + value_2 > 1000 -> "1" + value_2 > 100 -> "2" + } + value_1 == 3 -> when {} + value_1 == 4 -> when (value_3) { + true -> "1" + false -> "2" + null -> "3" + } + value_1 == 5 -> when (value_3) { + true -> "1" + false -> "2" + } + value_1 == 6 -> when (value_3) {} + } +} + +// TESTCASE NUMBER: 6 +fun case_6(value_1: Int, value_2: Int, value_3: Boolean?) = when { + value_1 == 1 -> when { + value_2 > 1000 -> 1 + value_2 > 100 -> 2 + else -> 3 + } + else -> when (value_3) { + true -> 1 + false -> 2 + null -> 3 + } +} + +// TESTCASE NUMBER: 7 +fun case_7(value_1: Int, value_2: Int, value_3: Boolean?) { + when { + value_1 == 1 -> if (value_2 > 1000) "1" + value_1 == 2 -> if (value_2 > 1000) "1" + else "2" + value_1 == 3 -> if (value_2 < 100) "1" + else if (value_2 < 10) "2" + else "4" + value_1 == 4 -> if (value_3 == null) "1" + else if (value_3) "2" + else if (!value_3) "3" + } +} + +// TESTCASE NUMBER: 8 +fun case_8(value_1: Int, value_2: Int) = when { + value_1 == 1 -> if (value_2 > 1000) "1" + else "2" + else -> if (value_2 < 100) "1" + else if (value_2 < 10) "2" + else "4" +} + +/* + * TESTCASE NUMBER: 9 + * UNEXPECTED BEHAVIOUR + * ISSUES: KT-37249 + */ +fun case_9(value_1: Int, value_2: String, value_3: String) = when { + value_1 == 1 -> try { 4 } catch (e: Exception) { 5 } + value_1 == 2 -> try { throw Exception() } catch (e: Exception) { value_2 } + else -> try { throw Exception() } catch (e: Exception) { {value_3} } finally { } +} + +// TESTCASE NUMBER: 10 +fun case_10(value_1: Int, value_2: String?, value_3: String?) { + when { + value_1 == 1 -> value_2 ?: true + value_1 == 2 -> value_2 ?: value_3 ?: true + value_1 == 3 -> value_2!! ?: true + } +} + +// TESTCASE NUMBER: 11 +fun case_11(value_1: Int) { + when { + value_1 == 1 -> 1..10 + value_1 == 2 -> -100L..100L + value_1 == 3 -> -getInt()..getLong() + } +} + +// TESTCASE NUMBER: 12 +fun case_12(value_1: Int, value_2: Collection, value_3: Collection?) { + when { + value_1 == 1 -> value_2 as List + value_1 == 2 -> value_2 as? List + value_1 == 3 -> value_3 as? MutableMap + value_1 == 4 -> (value_2 as? Map) as MutableMap + } +} + +// TESTCASE NUMBER: 13 +fun case_13(value_1: Int, value_2: Int, value_3: Int, value_4: Boolean) { + var mutablevalue_2 = value_2 + var mutablevalue_3 = value_3 + + when { + value_1 == 1 -> ++mutablevalue_2 + value_1 == 2 -> --mutablevalue_3 + value_1 == 3 -> !value_4 + } +} + +// TESTCASE NUMBER: 14 +fun case_14(value_1: Int, value_2: Int, value_3: Int, value_4: Boolean?) { + var mutablevalue_2 = value_2 + var mutablevalue_3 = value_3 + + when { + value_1 == 1 -> mutablevalue_2++ + value_1 == 2 -> mutablevalue_3-- + value_1 == 3 -> value_4!! + } +} + +// TESTCASE NUMBER: 15 +fun case_15(value_1: Int, value_2: List, value_3: List>>>) { + when { + value_1 == 1 -> value_2[0] + value_1 == 2 -> value_3[0][-4][1][-1] + } +} + +// TESTCASE NUMBER: 16 +fun case_16(value_1: Int, value_2: Class, value_3: Class?, value_4: Int) { + fun __fun_1(): () -> Unit { return fun() { } } + + when { + value_1 == 1 -> funWithoutArgs() + value_1 == 2 -> __fun_1()() + value_1 == 3 -> value_2.fun_2(value_4) + value_1 == 4 -> value_3?.fun_2(value_4) + value_1 == 5 -> value_3!!.fun_2(value_4) + } +} + +// TESTCASE NUMBER: 17 +fun case_17(value_1: Int, value_2: Class, value_3: Class?) { + when { + value_1 == 1 -> value_2.prop_1 + value_1 == 2 -> value_3?.prop_1 + value_1 == 3 -> value_2::prop_1.get() + value_1 == 4 -> value_3!!::prop_3.get() + } +} + +// TESTCASE NUMBER: 18 +fun case_18(value_1: Int) { + val fun_1 = fun(): Int { return 0 } + + when { + value_1 == 1 -> fun() {} + value_1 == 2 -> fun(): Int { return 0 } + value_1 == 3 -> fun(): () -> Unit { return fun() {} } + value_1 == 4 -> fun_1 + } +} + +// TESTCASE NUMBER: 19 +fun case_19(value_1: Int): () -> Any { + val lambda_1 = { 0 } + + return when { + value_1 == 1 -> lambda_1 + value_1 == 2 -> { { {} } } + else -> { -> (Int) + { arg: Int -> { { println(arg) } } } + } + } +} + +// TESTCASE NUMBER: 20 +fun case_20(value_1: Int) { + val object_1 = object { + val prop_1 = 1 + } + + when { + value_1 == 1 -> object {} + value_1 == 2 -> object { + private fun fun_1() { } + val prop_1 = 1 + } + value_1 == 3 -> object_1 + } +} + +// TESTCASE NUMBER: 21 +class A { + val prop_1 = 1 + val lambda_1 = { 1 } + fun fun_1(): Int { return 1 } + + fun case_21(value_1: Int) { + when { + value_1 == 1 -> this + value_1 == 2 -> ((this)) + value_1 == 3 -> this::prop_1.get() + value_1 == 4 -> this.prop_1 + value_1 == 5 -> this.lambda_1() + value_1 == 6 -> this::lambda_1.get()() + value_1 == 7 -> this.fun_1() + value_1 == 8 -> this::fun_1.invoke() + } + } +} + +// TESTCASE NUMBER: 22 +fun case_22(value_1: Int) { + when { + value_1 == 1 -> throw Exception() + value_1 == 2 -> throw throw throw Exception() + } +} + +// TESTCASE NUMBER: 23 +fun case_23(value_1: Int) { + fun r_1() { + when { + value_1 == 1 -> return + value_1 == 2 -> return return return + } + } + + fun r_2(): List? { + when { + value_1 == 1 -> return listOf(0, 1, 2) + value_1 == 2 -> return null + } + + return null + } +} + +// TESTCASE NUMBER: 24 +fun case_24(value_1: Int) { + loop1@ while (true) { + loop2@ while (true) { + when { + value_1 == 1 -> continue@loop1 + value_1 == 2 -> continue@loop2 + } + } + } +} + +// TESTCASE NUMBER: 25 +fun case_25(value_1: Int) { + loop1@ while (true) { + loop2@ while (true) { + when { + value_1 == 1 -> break@loop1 + value_1 == 2 -> break@loop2 + } + } + } +} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-2/pos/1.2.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-2/pos/1.2.fir.kt new file mode 100644 index 00000000000..83964f37908 --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-2/pos/1.2.fir.kt @@ -0,0 +1,32 @@ +// SKIP_TXT + +/* + * KOTLIN DIAGNOSTICS SPEC TEST (POSITIVE) + * + * SPEC VERSION: 0.1-100 + * PLACE: expressions, when-expression -> paragraph 2 -> sentence 1 + * NUMBER: 2 + * DESCRIPTION: Allowed break and continue in the control structure body of when. + */ + +// TESTCASE NUMBER: 1 +fun case_1(value_1: Int): String { + while (true) { + when { + value_1 == 1 -> break + } + } + + return "" +} + +// TESTCASE NUMBER: 2 +fun case_2(value_1: Int): String { + while (true) { + when { + value_1 == 1 -> continue + } + } + + return "" +} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-2/pos/2.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-2/pos/2.1.fir.kt new file mode 100644 index 00000000000..b77ce1b88f3 --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-2/pos/2.1.fir.kt @@ -0,0 +1,122 @@ +// SKIP_TXT + +/* + * KOTLIN DIAGNOSTICS SPEC TEST (POSITIVE) + * + * SPEC VERSION: 0.1-100 + * PLACE: expressions, when-expression -> paragraph 2 -> sentence 2 + * NUMBER: 1 + * DESCRIPTION: When without bound value, various boolean values in the when condition. + * HELPERS: typesProvider, enumClasses, sealedClasses, classes + */ + +// TESTCASE NUMBER: 1 +fun case_1(value_1: Boolean, value_2: Long): Int { + return when { + value_1 -> 1 + getBoolean() && value_1 -> 2 + getChar() != 'a' -> 3 + Out() === getAny() -> 4 + value_2 <= 11 -> 5 + !value_1 -> 6 + else -> 7 + } +} + +/* + * TESTCASE NUMBER: 2 + * NOTE: for a potential analysys of exhaustiveness by enums in whens without a bound value. + */ +fun case_2(value_1: EnumClass) { + when { + value_1 == EnumClass.NORTH -> {} + value_1 == EnumClass.SOUTH -> {} + value_1 == EnumClass.WEST -> {} + value_1 == EnumClass.EAST -> {} + } +} + +/* + * TESTCASE NUMBER: 3 + * NOTE: for a potential analysys of exhaustiveness by enums in whens without a bound value. + */ +fun case_3(value_1: Boolean) { + when { + value_1 == true -> return + value_1 == false -> return + } +} + +/* + * TESTCASE NUMBER: 4 + * NOTE: for a potential mark the code after the true branch as unreacable. + */ +fun case_4(value_1: Boolean) { + when { + false -> return + true -> return + value_1 -> return + } +} + +/* + * TESTCASE NUMBER: 5 + * NOTE: for a potential const propagation. + */ +fun case_5(value_1: Boolean) { + val value_2 = false + val value_3 = false || !!!false || false + + when { + value_3 -> return + value_2 -> return + value_1 -> return + } +} + +// TESTCASE NUMBER: 6 +fun case_6(value_1: Any) { + when { + value_1 is Nothing -> {} + value_1 is Int -> {} + value_1 is Boolean -> {} + value_1 is String -> {} + value_1 is Number -> {} + value_1 is Float -> {} + value_1 is Any -> {} + } +} + +/* + * TESTCASE NUMBER: 7 + * NOTE: for a potential analysys of exhaustiveness by enums in whens without a bound value. + */ +fun case_7(value_1: Any) { + when { + value_1 !is Number -> {} + value_1 is Float -> {} + value_1 is Number -> {} + value_1 is Any -> {} + } +} + +/* + * TESTCASE NUMBER: 8 + * NOTE: for a potential analysys of exhaustiveness by enums in whens without a bound value. + */ +fun case_8(value_1: SealedClass) { + when { + value_1 is SealedChild1 -> {} + value_1 is SealedChild2 -> {} + value_1 is SealedChild3 -> {} + } +} + +// TESTCASE NUMBER: 9 +fun case_9(value_1: Int, value_2: IntRange) { + when { + value_1 in -10..100L -> {} + value_1 in value_2 -> {} + value_1 !in listOf(0, 1, 2) -> {} + } +} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-2/pos/2.3.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-2/pos/2.3.fir.kt new file mode 100644 index 00000000000..ee1d7a39009 --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-2/pos/2.3.fir.kt @@ -0,0 +1,97 @@ +// SKIP_TXT + +/* + * KOTLIN DIAGNOSTICS SPEC TEST (POSITIVE) + * + * SPEC VERSION: 0.1-100 + * PLACE: expressions, when-expression -> paragraph 2 -> sentence 2 + * NUMBER: 3 + * DESCRIPTION: 'When' without bound value and with Nothing in condition (subtype of Boolean). + * DISCUSSION + * ISSUES: KT-25948 + * HELPERS: typesProvider + */ + +// TESTCASE NUMBER: 1 +fun case_1(value_1: TypesProvider) { + when { + return -> return + return == return -> return + return return return -> return + return != 10L -> return + return || return && return -> return + } +} + +// TESTCASE NUMBER: 2 +fun case_2(value_1: TypesProvider) { + when { + throw Exception() -> return + (throw Exception()) == (throw Exception()) -> return + (throw Exception()) && (throw Exception()) || (throw Exception()) -> return + (throw Exception()) == 10L -> return + throw throw throw throw Exception() -> return + } +} + +// TESTCASE NUMBER: 3 +fun case_3(value_1: TypesProvider) { + loop1@ while (true) { + loop2@ while (true) { + loop3@ while (true) { + when { + break@loop1 == break@loop2 -> return + break@loop2 || break@loop1 && break@loop3 -> return + break@loop2 != 10L -> return + } + } + } + } +} + +// TESTCASE NUMBER: 4 +fun case_4(value_1: TypesProvider): String { + loop1@ while (true) { + loop2@ while (true) { + loop3@ while (true) { + when { + continue@loop1 == continue@loop2 -> return "" + continue@loop2 || continue@loop1 && continue@loop3 -> return "" + continue@loop2 != 10L -> return "" + } + } + } + } +} + +// TESTCASE NUMBER: 6 +fun case_6(value_1: Nothing, value_2: TypesProvider): String { + when { + value_1 -> return "" + value_2.getNothing() -> return "" + getNothing() -> return "" + value_1 && (getNothing() == value_2.getNothing()) -> return "" + } + + return "" +} + +// TESTCASE NUMBER: 5 +fun case_5(value_1: TypesProvider, value_2: Nothing) { + loop1@ while (true) { + loop2@ while (true) { + loop3@ while (true) { + when { + continue@loop1 == throw throw throw throw Exception() -> return + (return return return return) || break@loop1 && break@loop3 -> return + continue@loop1 != 10L && (return return) == continue@loop1 -> return + return continue@loop1 -> return + (throw break@loop1) && break@loop3 -> return + (throw getNothing()) && value_1.getNothing() -> return + return return return value_2 -> return + getNothing() != 10L && (return return) == value_2 -> return + } + } + } + } +} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-3/neg/2.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-3/neg/2.1.fir.kt new file mode 100644 index 00000000000..3928ab279ef --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-3/neg/2.1.fir.kt @@ -0,0 +1,54 @@ +// !LANGUAGE: +NewInference +// !DIAGNOSTICS: -UNUSED_VARIABLE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE -UNUSED_PARAMETER -UNUSED_EXPRESSION +// SKIP_TXT + +/* + * KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE) + * + * SPEC VERSION: 0.1-218 + * PLACE: expressions, when-expression -> paragraph 3 -> sentence 2 + * NUMBER: 1 + * DESCRIPTION: The else condition must also be in the last when entry of when expression, otherwise it is a compile-time error + */ + +// FILE: JavaEnum.java +enum JavaEnum { + Val_1, + Val_2, + Val_3, +} + +// FILE: KotlinClass.kt + + +// TESTCASE NUMBER: 1 + +fun case1() { + val z = JavaEnum.Val_3 + val when1 = when (z) { + JavaEnum.Val_1 -> { false } + else -> {true} + JavaEnum.Val_2 -> { false } + } +} + +// TESTCASE NUMBER: 2 + +fun case2() { + val z = JavaEnum.Val_3 + val when1 = when (z) { + else -> {true} + JavaEnum.Val_1 -> { false } + JavaEnum.Val_2 -> { false } + } +}// TESTCASE NUMBER: 3 + +fun case3() { + val z = JavaEnum.Val_3 + val when1 = when (z) { + else -> {true} + JavaEnum.Val_1 -> { false } + JavaEnum.Val_2 -> { false } + else -> { true } + } +} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-4/neg/1.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-4/neg/1.1.fir.kt new file mode 100644 index 00000000000..42aea0b7a0e --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-4/neg/1.1.fir.kt @@ -0,0 +1,69 @@ +// !LANGUAGE: +NewInference +// !DIAGNOSTICS: -UNUSED_VARIABLE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE -UNUSED_PARAMETER -UNUSED_EXPRESSION +// SKIP_TXT +// FULL_JDK + +/* + * KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE) + * + * SPEC VERSION: 0.1-313 + * PLACE: expressions, when-expression -> paragraph 4 -> sentence 1 + * NUMBER: 1 + * DESCRIPTION: it is possible to replace the else condition with an always-true condition + */ + +// FILE: JavaEnum.java + +enum JavaEnum { + Val_1, + Val_2, +} + +// FILE: KotlinClass.kt + +// TESTCASE NUMBER: 1 +fun case1() { + val z = JavaEnum.Val_1 + val when2 = when (z) { + JavaEnum.Val_1 -> { } + JavaEnum.Val_1 -> { } + } + +} + +// TESTCASE NUMBER: 2 + +fun case2() { + val b = false + val when2: Any = when (b) { + false -> { } + false -> { } + } +} + +// TESTCASE NUMBER: 3 + +fun case3() { + val a = false + val when2: Any = when (a) { + true -> { } + true -> { } + } +} + +// TESTCASE NUMBER: 4 + +fun case4() { + val x: SClass = SClass.B() + val when2 = when (x){ + is SClass.A ->{ } + is SClass.B ->{ } + is SClass.B ->{ } + } +} + +sealed class SClass { + class A : SClass() + class B : SClass() + class C : SClass() +} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-4/pos/1.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-4/pos/1.1.fir.kt new file mode 100644 index 00000000000..acd3b7ff566 --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-4/pos/1.1.fir.kt @@ -0,0 +1,114 @@ +// !LANGUAGE: +NewInference +// !DIAGNOSTICS: -UNUSED_VARIABLE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE -UNUSED_PARAMETER -UNUSED_EXPRESSION +// SKIP_TXT +// FULL_JDK + +/* + * KOTLIN DIAGNOSTICS SPEC TEST (POSITIVE) + * + * SPEC VERSION: 0.1-313 + * PLACE: expressions, when-expression -> paragraph 4 -> sentence 1 + * NUMBER: 1 + * DESCRIPTION: it is possible to replace the else condition with an always-true condition + */ + +// FILE: JavaEnum.java + +enum JavaEnum { + Val_1, + Val_2, +} + +// FILE: KotlinClass.kt + +// TESTCASE NUMBER: 1 +fun case1() { + val z = JavaEnum.Val_1 + val when1 = when (z) { + JavaEnum.Val_1 -> { } + JavaEnum.Val_2 -> { } + else -> {} + } + + val when2 = when (z) { + JavaEnum.Val_1 -> { } + JavaEnum.Val_2 -> { } + } + val when3 = when (z) { + JavaEnum.Val_1 -> { } + JavaEnum.Val_2 -> { } + JavaEnum.Val_2 -> { } + } +} + +// TESTCASE NUMBER: 2 + +fun case2() { + val b = false + val when1: Any = when (b) { + false -> { } + !false -> { } + else -> { } + } + + val when2: Any = when (b) { + false -> { } + !false -> { } + } + val when3: Any = when (b) { + false -> { } + false -> { } + !false -> { } + } +} + +// TESTCASE NUMBER: 3 + +fun case3() { + val a = false + val when1: Any = when (a) { + true -> { } + false -> { } + else -> { } + } + val when2: Any = when (a) { + true -> { } + false -> { } + } + val when3: Any = when (a) { + true -> { } + false -> { } + false -> { } + } +} + +// TESTCASE NUMBER: 4 + +fun case4() { + val x: SClass = SClass.B() + + val when1 = when (x){ + is SClass.A ->{ } + is SClass.B ->{ } + is SClass.C ->{ } + else -> { } + } + + val when2 = when (x){ + is SClass.A ->{ } + is SClass.B ->{ } + is SClass.C ->{ } + } + val when3 = when (x){ + is SClass.A ->{ } + is SClass.B ->{ } + is SClass.B ->{ } + is SClass.C ->{ } + } +} + +sealed class SClass { + class A : SClass() + class B : SClass() + class C : SClass() +} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-5/pos/1.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-5/pos/1.1.fir.kt new file mode 100644 index 00000000000..9a9dc749ac1 --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-5/pos/1.1.fir.kt @@ -0,0 +1,326 @@ +// !DIAGNOSTICS: -UNUSED_EXPRESSION +// SKIP_TXT + +/* + * KOTLIN DIAGNOSTICS SPEC TEST (POSITIVE) + * + * SPEC VERSION: 0.1-313 + * PLACE: expressions, when-expression -> paragraph 5 -> sentence 1 + * NUMBER: 1 + * DESCRIPTION: 'When' with bound value and with different variants of expressions in the control structure body. + * HELPERS: typesProvider, classes, functions + */ + +// TESTCASE NUMBER: 1 +fun case_1(value_1: Int) { + when (value_1) { + 1 -> true + 2 -> 100 + 3 -> -.09f + 4 -> '.' + 5 -> "..." + 6 -> null + } +} + +// TESTCASE NUMBER: 2 +fun case_2(value_1: Int, value_2: Byte, value_3: TypesProvider) { + when (value_1) { + 1 -> -.09 % 10L + 3 -> value_2 / -5 + 2 -> value_3.getChar() - 11 + 90 + 4 -> 100 + } +} + +// TESTCASE NUMBER: 3 +fun case_3(value_1: Int, value_2: Boolean, value_3: Long) { + when (value_1) { + 1 -> value_2 + 2 -> !value_2 + 3 -> getBoolean() && value_2 + 5 -> getChar() != 'a' + 6 -> getList() === getAny() + 7 -> value_3 <= 11 + } +} + +// TESTCASE NUMBER: 4 +fun case_4(value_1: Int, value_2: String, value_3: String) { + when (value_1) { + 1 -> "..." + value_2 + "" + "$value_3" + "..." + 2 -> value_2 + getString() + } +} + +// TESTCASE NUMBER: 5 +fun case_5(value_1: Int, value_2: Int, value_3: Boolean?) { + when (value_1) { + 1 -> when (value_3) { + value_2 > 1000 -> "1" + value_2 > 100 -> "2" + else -> "3" + } + 2 -> when (value_3) { + value_2 > 1000 -> "1" + value_2 > 100 -> "2" + } + 3 -> when (value_3) {} + 4 -> when (value_3) { + true -> "1" + false -> "2" + null -> "3" + } + 5 -> when (value_3) { + true -> "1" + false -> "2" + } + 6 -> when (value_3) {} + } +} + +// TESTCASE NUMBER: 6 +fun case_6(value_1: Int, value_2: Int, value_3: Boolean?) = when (value_1) { + 1 -> when (value_3) { + value_2 > 1000 -> 1 + value_2 > 100 -> 2 + else -> 3 + } + else -> when (value_3) { + true -> 1 + false -> 2 + null -> 3 + } +} + +// TESTCASE NUMBER: 7 +fun case_7(value_1: Int, value_2: Int, value_3: Boolean?) { + when (value_1) { + 1 -> if (value_2 > 1000) "1" + 2 -> if (value_2 > 1000) "1" + else "2" + 3 -> if (value_2 < 100) "1" + else if (value_2 < 10) "2" + else "4" + 4 -> if (value_3 == null) "1" + else if (value_3) "2" + else if (!value_3) "3" + } +} + +// TESTCASE NUMBER: 8 +fun case_8(value_1: Int, value_2: Int) = when (value_1) { + 1 -> if (value_2 > 1000) "1" + else "2" + else -> if (value_2 < 100) "1" + else if (value_2 < 10) "2" + else "4" +} + +/* + * TESTCASE NUMBER: 9 + * UNEXPECTED BEHAVIOUR + * ISSUES: KT-37249 + */ +fun case_9(value_1: Int, value_2: String, value_3: String): Any { + return when (value_1) { + 1 -> try { 4 } catch (e: Exception) { 5 } + 2 -> try { throw Exception() } catch (e: Exception) { value_2 } + else -> try { throw Exception() } catch (e: Exception) { {value_3} } finally { } + } +} + +// TESTCASE NUMBER: 10 +fun case_10(value_1: Int, value_2: String?, value_3: String?) { + when (value_1) { + 1 -> value_2 ?: true + 2 -> value_2 ?: value_3 ?: true + 3 -> value_2!! ?: true + } +} + +// TESTCASE NUMBER: 11 +fun case_11(value_1: Int) { + when (value_1) { + 1 -> 1..10 + 2 -> -100L..100L + 3 -> -getInt()..getLong() + } +} + +// TESTCASE NUMBER: 12 +fun case_12(value_1: Int, value_2: Collection, value_3: Collection?) { + when (value_1) { + 1 -> value_2 as List + 2 -> value_2 as? List + 3 -> value_3 as? MutableMap + 4 -> (value_2 as? Map) as MutableMap + } +} + +// TESTCASE NUMBER: 13 +fun case_13(value_1: Int, value_2: Int, value_3: Int, value_4: Boolean) { + var mutableValue1 = value_2 + var mutableValue2 = value_3 + + when (value_1) { + 1 -> ++mutableValue1 + 2 -> --mutableValue2 + 3 -> !value_4 + } +} + +// TESTCASE NUMBER: 14 +fun case_14(value_1: Int, value_2: Int, value_3: Int, value_4: Boolean?) { + var mutableValue1 = value_2 + var mutableValue2 = value_3 + + when (value_1) { + 1 -> mutableValue1++ + 2 -> mutableValue2-- + 3 -> value_4!! + } +} + +// TESTCASE NUMBER: 15 +fun case_15(value_1: Int, value_2: List, value_3: List>>>) { + when (value_1) { + 1 -> value_2[0] + 2 -> value_3[0][-4][1][-1] + } +} + +// TESTCASE NUMBER: 16 +fun case_16(value_1: Int, value_2: Class, value_3: Class?, value_4: Int) { + fun __fun_1(): () -> Unit { return fun() { } } + + when (value_1) { + 1 -> funWithoutArgs() + 2 -> __fun_1()() + 3 -> value_2.fun_2(value_4) + 4 -> value_3?.fun_2(value_4) + 5 -> value_3!!.fun_2(value_4) + } +} + +// TESTCASE NUMBER: 17 +fun case_17(value_1: Int, value_2: Class, value_3: Class?) { + when (value_1) { + 1 -> value_2.prop_1 + 2 -> value_3?.prop_1 + 3 -> value_2::prop_1.get() + 4 -> value_3!!::prop_3.get() + } +} + +// TESTCASE NUMBER: 18 +fun case_18(value_1: Int) { + val fun_1 = fun(): Int { return 0 } + + when (value_1) { + 1 -> fun() {} + 2 -> fun(): Int { return 1 } + 3 -> fun(): () -> Unit { return fun() {} } + 4 -> fun_1 + } +} + +// TESTCASE NUMBER: 19 +fun case_19(value_1: Int): Any { + val lambda_1 = { 0 } + + return when (value_1) { + 1 -> lambda_1 + 2 -> { { {} } } + else -> { -> (Int) + { arg: Int -> { { println(arg) } } } + } + } +} + +// TESTCASE NUMBER: 20 +fun case_20(value_1: Int) { + val object_1 = object { + val prop_1 = 1 + } + + when (value_1) { + 1 -> object {} + 2 -> object { + private fun fun_1() { } + val prop_1 = 1 + } + 3 -> object_1 + } +} + +// TESTCASE NUMBER: 21 +class A { + val prop_1 = 1 + val lambda_1 = { 1 } + fun fun_1(): Int { return 1 } + + fun case_21(value_1: Int) { + when (value_1) { + 1 -> this + 2 -> ((this)) + 3 -> this::prop_1.get() + 4 -> this.prop_1 + 5 -> this.lambda_1() + 6 -> this::lambda_1.get()() + 7 -> this.fun_1() + 8 -> this::fun_1.invoke() + } + } +} + +// TESTCASE NUMBER: 22 +fun case_22(value_1: Int) { + when (value_1) { + 1 -> throw Exception() + 2 -> throw throw throw Exception() + } +} + +// TESTCASE NUMBER: 23 +fun case_23(value_1: Int) { + fun r_1() { + when (value_1) { + 1 -> return + 2 -> return return return + } + } + + fun r_2(): List? { + when (value_1) { + 1 -> return listOf(0, 1, 2) + 2 -> return null + } + + return null + } +} + +// TESTCASE NUMBER: 24 +fun case_24(value_1: Int) { + loop1@ while (true) { + loop2@ while (true) { + when (value_1) { + 1 -> continue@loop1 + 2 -> continue@loop2 + } + } + } +} + +// TESTCASE NUMBER: 25 +fun case_25(value_1: Int) { + loop1@ while (true) { + loop2@ while (true) { + when (value_1) { + 1 -> break@loop1 + 2 -> break@loop2 + } + } + } +} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-5/pos/1.2.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-5/pos/1.2.fir.kt new file mode 100644 index 00000000000..0be09e9d89e --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-5/pos/1.2.fir.kt @@ -0,0 +1,34 @@ +// SKIP_TXT + +/* + * KOTLIN DIAGNOSTICS SPEC TEST (POSITIVE) + * + * SPEC VERSION: 0.1-313 + * PLACE: expressions, when-expression -> paragraph 5 -> sentence 1 + * NUMBER: 2 + * DESCRIPTION: 'When' with bound value and allowed break and continue expression (without labels) in the control structure body. + */ + +// TESTCASE NUMBER: 1 +fun case_1(value_1: Int): Int { + while (true) { + when (value_1) { + 1 -> return 1 + 2 -> break + } + } + + return 0 +} + +// TESTCASE NUMBER: 2 +fun case_2(value_1: Int): Int { + while (true) { + when (value_1) { + 1 -> continue + 2 -> return 1 + } + } + + return 0 +} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/neg/1.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/neg/1.1.fir.kt new file mode 100644 index 00000000000..167a553e5a3 --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/neg/1.1.fir.kt @@ -0,0 +1,38 @@ +// SKIP_TXT + +/* + * KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE) + * + * SPEC VERSION: 0.1-296 + * PLACE: expressions, when-expression -> paragraph 6 -> sentence 1 + * NUMBER: 1 + * DESCRIPTION: 'When' with bound value and type test condition (without companion object in classes), but without type checking operator. + * HELPERS: classes + */ + +// TESTCASE NUMBER: 1 +fun case_1(value_1: Any): String { + when (value_1) { + EmptyClass -> return "" + } + + return "" +} + +// TESTCASE NUMBER: 2 +fun case_2(value_1: Any): String { + when (value_1) { + Any -> return "" + } + + return "" +} + +// TESTCASE NUMBER: 3 +fun case_3(value_1: Any): String { + when (value_1) { + Nothing -> return "" + } + + return "" +} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/neg/1.2.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/neg/1.2.fir.kt new file mode 100644 index 00000000000..c509e110fd1 --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/neg/1.2.fir.kt @@ -0,0 +1,20 @@ +// SKIP_TXT + +/* + * KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE) + * + * SPEC VERSION: 0.1-296 + * PLACE: expressions, when-expression -> paragraph 6 -> sentence 1 + * NUMBER: 2 + * DESCRIPTION: 'When' with bound value and type test condition on the non-type operand of the type checking operator. + * HELPERS: classes + */ + +// TESTCASE NUMBER: 1 +fun case_1(value_1: Any, value_2: Int): String { + when (value_1) { + is value_2 -> return "" + } + + return "" +} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/neg/11.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/neg/11.1.fir.kt new file mode 100644 index 00000000000..c70cd68a5d9 --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/neg/11.1.fir.kt @@ -0,0 +1,35 @@ +// !DIAGNOSTICS: -UNUSED_VALUE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE +// SKIP_TXT + +/* + * KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE) + * + * SPEC VERSION: 0.1-201 + * PLACE: expressions, when-expression -> paragraph 6 -> sentence 11 + * NUMBER: 1 + * DESCRIPTION: 'When' with bound value and non-expressions in 'when condition'. + */ + +// TESTCASE NUMBER: 1 +fun case_1(value_1: Int, value_2: List): String { + when (value_1) { + while (false) {} -> return "" + do {} while (false) -> return "" + for (value in value_2) {} -> return "" + } + + return "" +} + +// TESTCASE NUMBER: 4 +fun case_4(value_1: Int): String { + var value_2: Int + var value_3 = 10 + + when (value_1) { + value_2 = 10 -> return "" + value_3 %= 10 -> return "" + } + + return "" +} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/neg/12.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/neg/12.1.fir.kt new file mode 100644 index 00000000000..adcead71bcc --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/neg/12.1.fir.kt @@ -0,0 +1,33 @@ +// SKIP_TXT + +/* + * KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE) + * + * SPEC VERSION: 0.1-201 + * PLACE: expressions, when-expression -> paragraph 6 -> sentence 12 + * NUMBER: 1 + * DESCRIPTION: 'When' without bound value and with 'else' branch not in the last position. + */ + +// TESTCASE NUMBER: 1 +fun case_1(value_1: Int): String = when { + else -> "" + value_1 == 1 -> "" +} + +// TESTCASE NUMBER: 2 +fun case_2(value_1: Int): String = when { + value_1 == 1 -> "" + else -> "" + value_1 == 2 -> "" +} + +// TESTCASE NUMBER: 3 +fun case_3(): String { + when { + else -> return "" + else -> return "" + } + + return "" +} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/neg/3.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/neg/3.1.fir.kt new file mode 100644 index 00000000000..e4239423538 --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/neg/3.1.fir.kt @@ -0,0 +1,21 @@ +// SKIP_TXT + +/* + * KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE) + * + * SPEC VERSION: 0.1-296 + * PLACE: expressions, when-expression -> paragraph 6 -> sentence 3 + * NUMBER: 1 + * DESCRIPTION: 'When' with bound value and 'when condition' with range expression, but without containment checking operator. + * HELPERS: typesProvider + */ + +// TESTCASE NUMBER: 1 +fun case_1(value_1: Int, value_2: TypesProvider): String { + when (value_1) { + -1000L..100 -> return "" + value_2.getInt()..getLong() -> return "" + } + + return "" +} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/neg/3.2.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/neg/3.2.fir.kt new file mode 100644 index 00000000000..e349394c65f --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/neg/3.2.fir.kt @@ -0,0 +1,36 @@ +// !DIAGNOSTICS: -UNUSED_EXPRESSION +// SKIP_TXT + +/* + * KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE) + * + * SPEC VERSION: 0.1-296 + * PLACE: expressions, when-expression -> paragraph 6 -> sentence 3 + * NUMBER: 2 + * DESCRIPTION: 'When' with bound value and 'when condition' with contains operator and type without defined contains operator. + * HELPERS: classes + */ + +// TESTCASE NUMBER: 1 +fun case_1(value_1: Int, value_2: EmptyClass, value_3: Int, value_4: Any): String { + when (value_1) { + in value_2 -> return "" + in value_3 -> return "" + in value_4 -> return "" + } + + return "" +} + +/* + * TESTCASE NUMBER: 2 + * DISCUSSION + * ISSUES: KT-25948 + */ +fun case_2(value_1: Int, value_3: Nothing) { + when (value_1) { + in value_3 -> {} + in throw Exception() -> {} + in return -> {} + } +} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/neg/7.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/neg/7.1.fir.kt new file mode 100644 index 00000000000..c0e7ab72e01 --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/neg/7.1.fir.kt @@ -0,0 +1,34 @@ +// !DIAGNOSTICS: -UNUSED_EXPRESSION +// SKIP_TXT + +/* + * KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE) + * + * SPEC VERSION: 0.1-313 + * PLACE: expressions, when-expression -> paragraph 6 -> sentence 7 + * NUMBER: 1 + * DESCRIPTION: 'When' with bound value and with else branch not in the last position. + */ + +// TESTCASE NUMBER: 1 +fun case_1(value_1: Int): String = when (value_1) { + else -> "" + 1 -> "" +} + +// TESTCASE NUMBER: 2 +fun case_2(value_1: Int): String = when (value_1) { + 1 -> "" + else -> "" + 2 -> "" +} + +// TESTCASE NUMBER: 3 +fun case_3(value_1: Int): String { + when (value_1) { + else -> return "" + else -> return "" + } + + return "" +} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/1.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/1.1.fir.kt new file mode 100644 index 00000000000..2711087ec7a --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/1.1.fir.kt @@ -0,0 +1,69 @@ +// SKIP_TXT + +/* + * KOTLIN DIAGNOSTICS SPEC TEST (POSITIVE) + * + * SPEC VERSION: 0.1-296 + * PLACE: expressions, when-expression -> paragraph 6 -> sentence 1 + * NUMBER: 1 + * DESCRIPTION: 'When' with bound value and type test condition. + * HELPERS: classes, objects + */ + +// TESTCASE NUMBER: 1 +fun case_1(value_1: Any): String { + when (value_1) { + is Int -> return "" + is Float -> return "" + is Double -> return "" + is String -> return "" + is Char -> return "" + is Boolean -> return "" + } + + return "" +} + +// TESTCASE NUMBER: 2 +fun case_2(value_1: Any?): String = when (value_1) { + is Int? -> "" // if value is null then this branch will be executed + is Float -> "" + else -> "" +} + +// TESTCASE NUMBER: 3 +fun case_3(value_1: Any?): String = when (value_1) { + is Any -> "" + else -> "" +} + +// TESTCASE NUMBER: 4 +fun case_4(value_1: Any): String = when (value_1) { + is Any? -> "" + else -> "" +} + +/* + * TESTCASE NUMBER: 5 + * UNEXPECTED BEHAVIOUR + * ISSUES: KT-22996 + */ +fun case_5(value_1: Any?): String = when (value_1) { + is Double -> "" + is Int? -> "" // if value is null then this branch will be executed + is String -> "" + is Float? -> "" // redundant nullable type check + is Char -> "" + is Boolean -> "" + else -> "" +} + +// TESTCASE NUMBER: 6 +fun case_6(value_1: Any): String { + when (value_1) { + is EmptyObject -> return "" + is ClassWithCompanionObject.Companion -> return "" + } + + return "" +} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/1.2.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/1.2.fir.kt new file mode 100644 index 00000000000..d53ca23ab15 --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/1.2.fir.kt @@ -0,0 +1,58 @@ +// SKIP_TXT + +/* + * KOTLIN DIAGNOSTICS SPEC TEST (POSITIVE) + * + * SPEC VERSION: 0.1-296 + * PLACE: expressions, when-expression -> paragraph 6 -> sentence 1 + * NUMBER: 2 + * DESCRIPTION: 'When' with bound value and type test condition (invert type checking operator). + * HELPERS: classes, sealedClasses, objects + */ + +// TESTCASE NUMBER: 1 +fun case_1(value_1: SealedClass) = when (value_1) { + !is SealedChild1 -> {} + !is SealedChild2 -> {} + !is SealedChild3 -> {} +} + +/* + * TESTCASE NUMBER: 2 + * UNEXPECTED BEHAVIOUR + * ISSUES: KT-22996 + */ +fun case_2(value_1: SealedClass?): String = when (value_1) { + !is SealedChild2 -> "" // including null + is SealedChild2 -> "" + null -> "" // redundant +} + +// TESTCASE NUMBER: 3 +fun case_3(value_1: SealedClass?): String = when (value_1) { + !is SealedChild2? -> "" // null isn't included + is SealedChild2 -> "" + null -> "" +} + +/* + * TESTCASE NUMBER: 4 + * UNEXPECTED BEHAVIOUR + * ISSUES: KT-22996 + */ +fun case_4(value_1: SealedClass?) { + when (value_1) { + !is SealedChild2 -> {} // including null + is SealedChild2? -> {} // redundant nullable type check + } +} + +// TESTCASE NUMBER: 5 +fun case_5(value_1: Any): String { + when (value_1) { + is EmptyObject -> return "" + !is ClassWithCompanionObject.Companion -> return "" + } + + return "" +} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/1.4.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/1.4.fir.kt new file mode 100644 index 00000000000..82f9507748d --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/1.4.fir.kt @@ -0,0 +1,59 @@ +// SKIP_TXT + +/* + * KOTLIN DIAGNOSTICS SPEC TEST (POSITIVE) + * + * SPEC VERSION: 0.1-296 + * PLACE: expressions, when-expression -> paragraph 6 -> sentence 1 + * NUMBER: 4 + * DESCRIPTION: 'When' with bound value and enumaration of type test conditions (with invert type checking operator). + * HELPERS: sealedClasses + */ + +// TESTCASE NUMBER: 1 +fun case_1(value_1: SealedClass): String = when (value_1) { + is SealedChild1, !is SealedChild3 -> "" + is SealedChild3 -> "" +} + +// TESTCASE NUMBER: 2 +fun case_2(value_1: SealedClass) = when (value_1) { + !is SealedChild1, !is SealedChild2, !is SealedChild3 -> {} +} + +// TESTCASE NUMBER: 3 +fun case_3(value_1: SealedClass): String = when (value_1) { + is SealedChild2, !is SealedChild2 -> "" +} + +// TESTCASE NUMBER: 4 +fun case_4(value_1: SealedClass): String = when (value_1) { + !is SealedChild1, is SealedChild1 -> "" +} + +// TESTCASE NUMBER: 5 +fun case_5(value_1: Any?): String = when (value_1) { + is SealedChild3, !is SealedChild3? -> "" + else -> "" +} + +/* + * TESTCASE NUMBER: 6 + * UNEXPECTED BEHAVIOUR + * ISSUES: KT-22996 + */ +fun case_6(value_1: Any?): String = when (value_1) { + is Boolean?, !is SealedChild3 -> "" // double nullable type check in the one branch + is SealedChild3 -> "" + else -> "" +} + +/* + * TESTCASE NUMBER: 7 + * UNEXPECTED BEHAVIOUR + * ISSUES: KT-22996 + */ +fun case_7(value_1: Any?): String = when (value_1) { + is Number?, null, !is SealedChild3 -> "" // triple nullable type check in the one branch + else -> "" +} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/10.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/10.1.fir.kt new file mode 100644 index 00000000000..73cc41c1c28 --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/10.1.fir.kt @@ -0,0 +1,286 @@ +// SKIP_TXT + +/* + * KOTLIN DIAGNOSTICS SPEC TEST (POSITIVE) + * + * SPEC VERSION: 0.1-201 + * PLACE: expressions, when-expression -> paragraph 6 -> sentence 10 + * NUMBER: 1 + * DESCRIPTION: 'When' with enumeration of the different variants of expressions in 'when condition'. + * HELPERS: typesProvider, classes, functions + */ + +// TESTCASE NUMBER: 1 +fun case_1(value_1: Any?) { + when (value_1) { + true -> {} + 100 -> {} + -.09f -> {} + '.' -> {} + "..." -> {} + null -> {} + } +} + +// TESTCASE NUMBER: 2 +fun case_2(value_1: Number, value_2: Int) { + when (value_1) { + -.09 % 10L -> {} + value_2 / -5 -> {} + getByte() - 11 + 90 -> {} + } +} + +// TESTCASE NUMBER: 3 +fun case_3(value_1: Boolean, value_2: Boolean, value_3: Long) { + when (value_1) { + value_2 -> {} + !value_2 -> {} + getBoolean() && value_2 -> {} + getChar() != 'a' -> {} + getList() === getAny() -> {} + value_3 <= 11 -> {} + } +} + +// TESTCASE NUMBER: 4 +fun case_4(value_1: String, value_2: String, value_3: String) { + when (value_1) { + "..." + value_2 + "" + "$value_3" + "..." -> {} + value_2 + getString() -> {} + } +} + +// TESTCASE NUMBER: 5 +fun case_5(value_1: Int, value_2: Int, value_3: Boolean?) { + when (value_1) { + when { + value_2 > 1000 -> 1 + value_2 > 100 -> 2 + else -> 3 + } -> {} + when (value_3) { + true -> 1 + false -> 2 + null -> 3 + } -> {} + when (value_3!!) { + true -> 1 + false -> 2 + } -> {} + } +} + +// TESTCASE NUMBER: 6 +fun case_6(value_1: Int, value_2: Int) { + when (value_1) { + if (value_2 > 1000) 1 + else 2 -> {} + if (value_2 < 100) 1 + else if (value_2 < 10) 2 + else 3 -> {} + } +} + +// TESTCASE NUMBER: 7 +fun case_7(value_1: Any, value_2: String, value_3: String) { + when (value_1) { + try { 4 } catch (e: Exception) { 5 } -> {} + try { throw Exception() } catch (e: Exception) { value_2 } -> {} + try { throw Exception() } catch (e: Exception) { {value_3} } finally { } -> {} + } +} + +// TESTCASE NUMBER: 8 +fun case_8(value_1: Int, value_2: Int?, value_3: Int?) { + when (value_1) { + value_2 ?: 0 -> {} + value_2 ?: value_3 ?: 0 -> {} + value_2!! ?: 0 -> {} + } +} + +// TESTCASE NUMBER: 9 +fun case_9(value_1: Any) { + when (value_1) { + 1..10 -> {} + -100L..100L -> {} + -getInt()..getLong() -> {} + } +} + +// TESTCASE NUMBER: 10 +fun case_10(value_1: Collection, value_2: Collection, value_3: Collection?) { + when (value_1) { + value_2 as List -> {} + value_2 as? List -> {} + value_3 as? MutableMap -> {} + (value_2 as? Map) as MutableMap -> {} + } +} + +// TESTCASE NUMBER: 11 +fun case_11(value_1: Any, value_2: Int, value_3: Int, value_4: Boolean) { + var mutableValue1 = value_2 + var mutableValue2 = value_3 + + when (value_1) { + ++mutableValue1 -> {} + --mutableValue2 -> {} + !value_4 -> {} + } +} + +// TESTCASE NUMBER: 12 +fun case_12(value_1: Int, value_2: Int, value_3: Int, value_4: Int?) { + var mutableValue1 = value_2 + var mutableValue2 = value_3 + + when (value_1) { + mutableValue1++ -> {} + mutableValue2-- -> {} + value_4!! -> {} + } +} + +// TESTCASE NUMBER: 13 +fun case_13(value_1: Int, value_2: List, value_3: List>>>) { + when (value_1) { + value_2[0] -> {} + value_3[0][-4][1][-1] -> {} + } +} + +// TESTCASE NUMBER: 14 +fun case_14(value_1: Any, value_2: Class, value_3: Class?, value_4: Int) { + fun __fun_1(): () -> Any { return fun() { } } + + when (value_1) { + funWithoutArgs() -> {} + __fun_1()() -> {} + value_2.fun_2(value_4) -> {} + value_3?.fun_2(value_4) -> {} + value_3!!.fun_2(value_4) -> {} + } +} + +// TESTCASE NUMBER: 15 +fun case_15(value_1: Int, value_2: Class, value_3: Class?) { + when (value_1) { + value_2.prop_1 -> {} + value_3?.prop_2 -> {} + value_2::prop_1.get() -> {} + value_3!!::prop_3.get() -> {} + } +} + +// TESTCASE NUMBER: 16 +fun case_16(value_1: () -> Any): Any { + val fun_1 = fun() { return } + + return when (value_1) { + fun() {} -> {} + fun() { return } -> {} + fun(): () -> Unit { return fun() {} } -> {} + fun_1 -> {} + else -> {} + } +} + +// TESTCASE NUMBER: 17 +fun case_17(value_1: () -> Any) { + val lambda_1 = { 0 } + + when (value_1) { + lambda_1 -> {} + { { {} } } -> {} + { -> (Int) + { arg: Int -> { { println(arg) } } } + } -> {} + } +} + +// TESTCASE NUMBER: 18 +fun case_18(value_1: Any) { + val object_1 = object { + val prop_1 = 1 + } + + when (value_1) { + object {} -> {} + object { + private fun fun_1() { } + val prop_1 = 1 + } -> {} + object_1 -> {} + } +} + +// TESTCASE NUMBER: 19 +class A { + val prop_1 = 1 + val lambda_1 = { 1 } + fun fun_1(): Int { return 1 } + + fun case_19(value_1: Any) { + when (value_1) { + this -> {} + ((this)) -> {} + this::prop_1.get() -> {} + this.prop_1 -> {} + this.lambda_1() -> {} + this::lambda_1.get()() -> {} + this.fun_1() -> {} + this::fun_1.invoke() -> {} + } + } +} + +// TESTCASE NUMBER: 20 +fun case_20(value_1: Nothing) { + when (value_1) { + throw Exception() -> {} + throw throw throw Exception() -> {} + } +} + +// TESTCASE NUMBER: 21 +fun case_21(value_1: Nothing) { + fun f1() { + when (value_1) { + return -> 1 + return return return -> 2 + } + } + + fun f2(): List? { + when (value_1) { + return listOf(0, 1, 2) -> 1 + return null -> 2 + } + } +} + +// TESTCASE NUMBER: 22 +fun case_22(value_1: Nothing) { + loop1@ while (true) { + loop2@ while (true) { + when (value_1) { + continue@loop1 -> 1 + continue@loop2 -> 2 + } + } + } +} + +// TESTCASE NUMBER: 23 +fun case_23(value_1: Nothing) { + loop1@ while (true) { + loop2@ while (true) { + when (value_1) { + break@loop1 -> 1 + break@loop2 -> 2 + } + } + } +} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/10.2.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/10.2.fir.kt new file mode 100644 index 00000000000..e704e80e78c --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/10.2.fir.kt @@ -0,0 +1,263 @@ +// SKIP_TXT + +/* + * KOTLIN DIAGNOSTICS SPEC TEST (POSITIVE) + * + * SPEC VERSION: 0.1-201 + * PLACE: expressions, when-expression -> paragraph 6 -> sentence 10 + * NUMBER: 2 + * DESCRIPTION: 'When' with different variants of the arithmetic expressions (additive expression and multiplicative expression) in 'when condition'. + * HELPERS: typesProvider, classes, functions + */ + +// TESTCASE NUMBER: 1 +fun case_1(value_1: Any?) { + when (value_1) { + true, 100, -.09f -> {} + '.', "...", null -> {} + } +} + +// TESTCASE NUMBER: 2 +fun case_2(value_1: Number, value_2: Int) { + when (value_1) { + -.09 % 10L, value_2 / -5, getByte() - 11 + 90 -> {} + } +} + +// TESTCASE NUMBER: 3 +fun case_3(value_1: Boolean, value_2: Boolean, value_3: Long) { + when (value_1) { + value_2, !value_2, getBoolean() && value_2, getChar() != 'a' -> {} + getList() === getAny(), value_3 <= 11 -> {} + } +} + +// TESTCASE NUMBER: 4 +fun case_4(value_1: String, value_2: String, value_3: String) { + when (value_1) { + "..." + value_2 + "" + "$value_3" + "...", value_2 + getString() -> {} + } +} + +// TESTCASE NUMBER: 5 +fun case_5(value_1: Int, value_2: Int, value_3: Boolean?) { + when (value_1) { + when { + value_2 > 1000 -> 1 + value_2 > 100 -> 2 + else -> 3 + }, when (value_3) { + true -> 1 + false -> 2 + null -> 3 + }, when (value_3!!) { + true -> 1 + false -> 2 + } -> {} + } +} + +// TESTCASE NUMBER: 6 +fun case_6(value_1: Int, value_2: Int) { + when (value_1) { + if (value_2 > 1000) 1 else 2, if (value_2 < 100) 1 else if (value_2 < 10) 2 else 3 -> {} + } +} + +// TESTCASE NUMBER: 7 +fun case_7(value_1: Any, value_2: String, value_3: String) { + when (value_1) { + try { 4 } catch (e: Exception) { 5 }, try { throw Exception() } catch (e: Exception) { value_2 }, try { throw Exception() } catch (e: Exception) { {value_3} } finally { } -> {} + } +} + +// TESTCASE NUMBER: 8 +fun case_8(value_1: Int, value_2: Int?, value_3: Int?) { + when (value_1) { + value_2 ?: 0, value_2 ?: value_3 ?: 0, value_2!! ?: 0 -> {} + } +} + +// TESTCASE NUMBER: 9 +fun case_9(value_1: Any) { + when (value_1) { + 1..10, -100L..100L, -getInt()..getLong() -> {} + } +} + +// TESTCASE NUMBER: 10 +fun case_10(value_1: Collection, value_2: Collection, value_3: Collection?) { + when (value_1) { + value_2 as List, value_2 as? List -> {} + value_3 as? MutableMap, (value_2 as? Map) as MutableMap -> {} + } +} + +// TESTCASE NUMBER: 11 +fun case_11(value_1: Any, value_2: Int, value_3: Int, value_4: Boolean) { + var mutableValue1 = value_2 + var mutableValue2 = value_3 + + when (value_1) { + ++mutableValue1, --mutableValue2, !value_4 -> {} + } +} + +// TESTCASE NUMBER: 12 +fun case_12(value_1: Int, value_2: Int, value_3: Int, value_4: Int?) { + var mutableValue1 = value_2 + var mutableValue2 = value_3 + + when (value_1) { + mutableValue1++, mutableValue2--, value_4!! -> {} + } +} + +// TESTCASE NUMBER: 13 +fun case_13(value_1: Int, value_2: List, value_3: List>>>) { + when (value_1) { + value_2[0], value_3[0][-4][1][-1] -> {} + } +} + +// TESTCASE NUMBER: 14 +fun case_14(value_1: Any, value_2: Class, value_3: Class?, value_4: Int) { + fun __fun_1(): () -> Unit { return fun() { } } + + when (value_1) { + funWithoutArgs(), __fun_1()(), value_2.fun_2(value_4) -> {} + value_3?.fun_2(value_4), value_3!!.fun_2(value_4) -> {} + } +} + +// TESTCASE NUMBER: 15 +fun case_15(value_1: Int, value_2: Class, value_3: Class?) { + when (value_1) { + value_2.prop_1, value_3?.prop_2 -> {} + value_2::prop_1.get(), value_3!!::prop_3.get() -> {} + } +} + +// TESTCASE NUMBER: 16 +fun case_16(value_1: () -> Any): Any { + val fun_1 = fun() { return } + + return when (value_1) { + fun() {}, fun() { return }, fun(): () -> Unit { return fun() {} }, fun_1 -> {} + else -> {} + } +} + +// TESTCASE NUMBER: 17 +fun case_17(value_1: () -> Any) { + val lambda_1 = { 0 } + + when (value_1) { + lambda_1, { { {} } }, { -> (Int) + { arg: Int -> { { println(arg) } } } } -> {} + } +} + +// TESTCASE NUMBER: 18 +fun case_18(value_1: Any) { + val object_1 = object { + val prop_1 = 1 + } + + when (value_1) { + object {}, object { + private fun fun_1() { } + val prop_1 = 1 + }, object_1 -> {} + } +} + +// TESTCASE NUMBER: 19 +class A { + val prop_1 = 1 + val lambda_1 = { 1 } + fun fun_1(): Int { return 1 } + + fun case_19(value_1: Any) { + when (value_1) { + this, ((this)), this::prop_1.get() -> {} + this.prop_1, this.lambda_1() -> {} + this::lambda_1.get()(), this.fun_1(), this::fun_1.invoke() -> {} + } + } +} + +// TESTCASE NUMBER: 20 +fun case_20(value_1: Nothing) { + when (value_1) { + throw Exception(), throw throw throw Exception() -> {} + } +} + +// TESTCASE NUMBER: 21 +fun case_21(value_1: Nothing) { + fun f1() { + when (value_1) { + return, return return return -> 2 + } + } + + fun f2(): List? { + when (value_1) { + return listOf(0, 1, 2), return null -> 2 + } + } +} + +// TESTCASE NUMBER: 22 +fun case_22(value_1: Nothing) { + loop1@ while (true) { + loop2@ while (true) { + when (value_1) { + continue@loop1, continue@loop2 -> 2 + } + } + } +} + +// TESTCASE NUMBER: 23 +fun case_23(value_1: Nothing) { + loop1@ while (true) { + loop2@ while (true) { + when (value_1) { + break@loop1, break@loop2 -> 2 + } + } + } +} + +// TESTCASE NUMBER: 24 +fun case_24(value_1: Nothing?) = when (value_1) { + throw Exception(), return "" -> "" + null, return return return "", throw throw throw Exception() -> "" + else -> "" +} + +/* + * TESTCASE NUMBER: 25 + * DISCUSSION + * ISSUES: KT-25948 + */ +fun case_25(value_1: Boolean) = when (value_1) { + true -> {} + throw Exception(), return -> {} + false, return return return, throw throw throw Exception() -> {} +} + +/* + * TESTCASE NUMBER: 26 + * UNEXPECTED BEHAVIOUR + * ISSUES: KT-26045 + */ +fun case_26(value_1: Int?, value_2: Class, value_3: Class?) { + when (value_1) { + value_2.prop_1, value_3?.prop_1 -> {} + 10 -> {} + } +} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/11.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/11.1.fir.kt new file mode 100644 index 00000000000..93101ec743e --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/11.1.fir.kt @@ -0,0 +1,32 @@ +// SKIP_TXT + +/* + * KOTLIN DIAGNOSTICS SPEC TEST (POSITIVE) + * + * SPEC VERSION: 0.1-201 + * PLACE: expressions, when-expression -> paragraph 6 -> sentence 11 + * NUMBER: 1 + * DESCRIPTION: 'When' with bound value and not allowed break and continue expression (without labels) in 'when condition'. + */ + +// TESTCASE NUMBER: 1 +fun case_1(value_1: Int): String { + while (true) { + when (value_1) { + break -> return "" + } + } + + return "" +} + +// TESTCASE NUMBER: 2 +fun case_2(value_1: Int): String { + while (true) { + when (value_1) { + continue -> return "" + } + } + + return "" +}