[FE 1.0] Report warning on non-exhaustive when statements only after 1.6

^KT-47709
This commit is contained in:
Dmitriy Novozhilov
2021-07-21 10:50:39 +03:00
committed by teamcityserver
parent 865ad3698b
commit a710a8d10f
33 changed files with 489 additions and 21 deletions
@@ -1,3 +1,4 @@
// LANGUAGE: +WarnAboutNonExhaustiveWhenOnAlgebraicTypes
/*
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
*
@@ -1,3 +1,4 @@
// LANGUAGE: +WarnAboutNonExhaustiveWhenOnAlgebraicTypes
/*
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
*
@@ -1,3 +1,4 @@
// LANGUAGE: +WarnAboutNonExhaustiveWhenOnAlgebraicTypes
/*
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
*
@@ -1,3 +1,4 @@
// LANGUAGE: +WarnAboutNonExhaustiveWhenOnAlgebraicTypes
/*
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
*
@@ -1,4 +1,5 @@
// FIR_IDENTICAL
// LANGUAGE: +WarnAboutNonExhaustiveWhenOnAlgebraicTypes
/*
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
*
@@ -1,3 +1,4 @@
// LANGUAGE: +WarnAboutNonExhaustiveWhenOnAlgebraicTypes
/*
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
*
@@ -1,3 +1,4 @@
// LANGUAGE: +WarnAboutNonExhaustiveWhenOnAlgebraicTypes
/*
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
*
@@ -1,4 +1,5 @@
// FIR_IDENTICAL
// LANGUAGE: +WarnAboutNonExhaustiveWhenOnAlgebraicTypes
/*
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
*
@@ -0,0 +1,154 @@
// !LANGUAGE: -WarnAboutNonExhaustiveWhenOnAlgebraicTypes -ProhibitNonExhaustiveWhenOnAlgebraicTypes
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) {
<!NON_EXHAUSTIVE_WHEN_STATEMENT!>when<!> (x) {
SomeEnum.A -> ""
}
}
fun test_2(x: Base) {
<!NON_EXHAUSTIVE_WHEN_STATEMENT!>when<!> (x) {
is Base.A -> ""
}
}
fun test_3(x: IBase) {
<!NON_EXHAUSTIVE_WHEN_STATEMENT!>when<!> (x) {
is IBase.A -> ""
}
}
fun test_4(x: Boolean) {
<!NON_EXHAUSTIVE_WHEN_STATEMENT!>when<!> (x) {
true -> ""
}
}
// ------------------ nullable ------------------
fun test_5(x: SomeEnum?) {
<!NON_EXHAUSTIVE_WHEN_STATEMENT!>when<!> (x) {
SomeEnum.A -> ""
SomeEnum.B -> ""
}
<!NON_EXHAUSTIVE_WHEN_STATEMENT!>when<!> (x) {
SomeEnum.A -> ""
null -> ""
}
}
fun test_6(x: Base?) {
<!NON_EXHAUSTIVE_WHEN_STATEMENT!>when<!> (x) {
is Base.A -> ""
is Base.B -> ""
}
<!NON_EXHAUSTIVE_WHEN_STATEMENT!>when<!> (x) {
is Base.A -> ""
null -> ""
}
}
fun test_7(x: IBase?) {
<!NON_EXHAUSTIVE_WHEN_STATEMENT!>when<!> (x) {
is IBase.A -> ""
is IBase.B -> ""
}
<!NON_EXHAUSTIVE_WHEN_STATEMENT!>when<!> (x) {
is IBase.A -> ""
null -> ""
}
}
fun test_8(x: Boolean?) {
<!NON_EXHAUSTIVE_WHEN_STATEMENT!>when<!> (x) {
true -> ""
false -> ""
}
<!NON_EXHAUSTIVE_WHEN_STATEMENT!>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 -> ""
}
}
@@ -0,0 +1,154 @@
// !LANGUAGE: -WarnAboutNonExhaustiveWhenOnAlgebraicTypes -ProhibitNonExhaustiveWhenOnAlgebraicTypes
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) {
<!NON_EXHAUSTIVE_WHEN!>when<!> (x) {
SomeEnum.A -> ""
}
}
fun test_2(x: Base) {
<!NON_EXHAUSTIVE_WHEN_ON_SEALED_CLASS!>when<!> (x) {
is Base.A -> ""
}
}
fun test_3(x: IBase) {
<!NON_EXHAUSTIVE_WHEN_ON_SEALED_CLASS!>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 -> ""
}
<!NON_EXHAUSTIVE_WHEN!>when<!> (x) {
SomeEnum.A -> ""
null -> ""
}
}
fun test_6(x: Base?) {
when (x) {
is Base.A -> ""
is Base.B -> ""
}
<!NON_EXHAUSTIVE_WHEN_ON_SEALED_CLASS!>when<!> (x) {
is Base.A -> ""
null -> ""
}
}
fun test_7(x: IBase?) {
when (x) {
is IBase.A -> ""
is IBase.B -> ""
}
<!NON_EXHAUSTIVE_WHEN_ON_SEALED_CLASS!>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 -> ""
}
}
@@ -0,0 +1,78 @@
package
public fun test_1(/*0*/ x: SomeEnum): kotlin.Unit
public fun test_10(/*0*/ x: Base?): kotlin.Unit
public fun test_11(/*0*/ x: IBase?): kotlin.Unit
public fun test_12(/*0*/ x: kotlin.Boolean?): kotlin.Unit
public fun test_13(/*0*/ x: SomeEnum?): kotlin.Unit
public fun test_14(/*0*/ x: Base?): kotlin.Unit
public fun test_15(/*0*/ x: IBase?): kotlin.Unit
public fun test_16(/*0*/ x: kotlin.Boolean?): kotlin.Unit
public fun test_2(/*0*/ x: Base): kotlin.Unit
public fun test_3(/*0*/ x: IBase): kotlin.Unit
public fun test_4(/*0*/ x: kotlin.Boolean): kotlin.Unit
public fun test_5(/*0*/ x: SomeEnum?): kotlin.Unit
public fun test_6(/*0*/ x: Base?): kotlin.Unit
public fun test_7(/*0*/ x: IBase?): kotlin.Unit
public fun test_8(/*0*/ x: kotlin.Boolean?): kotlin.Unit
public fun test_9(/*0*/ x: SomeEnum?): kotlin.Unit
public sealed class Base {
protected constructor Base()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public final class A : Base {
public constructor A()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class B : Base {
public constructor B()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
public sealed interface IBase {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public interface A : IBase {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface B : IBase {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
public final enum class SomeEnum : kotlin.Enum<SomeEnum> {
enum entry A
enum entry B
private constructor SomeEnum()
public final override /*1*/ /*fake_override*/ val name: kotlin.String
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: SomeEnum): kotlin.Int
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit
public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class<SomeEnum!>!
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
// Static members
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): SomeEnum
public final /*synthesized*/ fun values(): kotlin.Array<SomeEnum>
}
@@ -1,5 +1,5 @@
// FIR_IDENTICAL
// !LANGUAGE: -ProhibitNonExhaustiveWhenOnAlgebraicTypes
// !LANGUAGE: +WarnAboutNonExhaustiveWhenOnAlgebraicTypes -ProhibitNonExhaustiveWhenOnAlgebraicTypes
enum class SomeEnum {
A, B
@@ -1,5 +1,5 @@
// FIR_IDENTICAL
// !LANGUAGE: +ProhibitNonExhaustiveWhenOnAlgebraicTypes
// !LANGUAGE: +WarnAboutNonExhaustiveWhenOnAlgebraicTypes +ProhibitNonExhaustiveWhenOnAlgebraicTypes
enum class SomeEnum {
A, B