[FIR] Add support of multiple condition branches to exhaustiveness checker

This commit is contained in:
Dmitriy Novozhilov
2019-11-11 11:45:25 +03:00
parent 86570a2f91
commit cf61a6c30f
5 changed files with 52 additions and 4 deletions
@@ -101,6 +101,12 @@ class FirWhenExhaustivenessTransformer(private val bodyResolveComponents: BodyRe
} }
} }
} }
override fun visitBinaryLogicExpression(binaryLogicExpression: FirBinaryLogicExpression, data: EnumExhaustivenessData) {
if (binaryLogicExpression.kind == LogicOperationKind.OR) {
binaryLogicExpression.acceptChildren(this, data)
}
}
} }
// ------------------------ Sealed class exhaustiveness ------------------------ // ------------------------ Sealed class exhaustiveness ------------------------
@@ -147,6 +153,12 @@ class FirWhenExhaustivenessTransformer(private val bodyResolveComponents: BodyRe
val symbol = data.symbolProvider.getSymbolByLookupTag(lookupTag) as? FirClassSymbol ?: return val symbol = data.symbolProvider.getSymbolByLookupTag(lookupTag) as? FirClassSymbol ?: return
data.visitedInheritors.replace(symbol.classId, true) data.visitedInheritors.replace(symbol.classId, true)
} }
override fun visitBinaryLogicExpression(binaryLogicExpression: FirBinaryLogicExpression, data: SealedExhaustivenessData) {
if (binaryLogicExpression.kind == LogicOperationKind.OR) {
binaryLogicExpression.acceptChildren(this, data)
}
}
} }
// ------------------------ Boolean exhaustiveness ------------------------ // ------------------------ Boolean exhaustiveness ------------------------
@@ -47,3 +47,10 @@ fun test_2(e: Enum?) {
else -> 4 else -> 4
} }
} }
fun test_3(e: Enum) {
val a = when (e) {
Enum.A, Enum.B -> 1
Enum.C -> 2
}
}
@@ -120,3 +120,14 @@ FILE: exhaustiveness_enum.kt
} }
} }
public final fun test_3(e: R|Enum|): R|kotlin/Unit| {
lval a: R|kotlin/Int| = when (R|<local>/e|) {
==($subj$, Q|Enum.A|) || ==($subj$, Q|Enum.B|) -> {
Int(1)
}
==($subj$, Q|Enum.C|) -> {
Int(2)
}
}
}
@@ -37,17 +37,24 @@ fun test_2(e: Base?) {
is C -> 3 is C -> 3
} }
val a = when (e) { val b = when (e) {
is Base.A -> 1 is Base.A -> 1
is Base.A.B -> 2 is Base.A.B -> 2
is C -> 3 is C -> 3
null -> 4 null -> 4
} }
val a = when (e) { val c = when (e) {
is Base.A -> 1 is Base.A -> 1
is Base.A.B -> 2 is Base.A.B -> 2
is C -> 3 is C -> 3
else -> 4 else -> 4
} }
} }
fun test_3(e: Base) {
val a = when (e) {
is Base.A, is Base.A.B -> 1
is C -> 2
}
}
@@ -82,7 +82,7 @@ FILE: exhaustiveness_sealedClass.kt
} }
} }
lval a: R|kotlin/Int| = when (R|<local>/e|) { lval b: R|kotlin/Int| = when (R|<local>/e|) {
($subj$ is R|Base.A|) -> { ($subj$ is R|Base.A|) -> {
Int(1) Int(1)
} }
@@ -97,7 +97,7 @@ FILE: exhaustiveness_sealedClass.kt
} }
} }
lval a: R|kotlin/Int| = when (R|<local>/e|) { lval c: R|kotlin/Int| = when (R|<local>/e|) {
($subj$ is R|Base.A|) -> { ($subj$ is R|Base.A|) -> {
Int(1) Int(1)
} }
@@ -113,3 +113,14 @@ FILE: exhaustiveness_sealedClass.kt
} }
} }
public final fun test_3(e: R|Base|): R|kotlin/Unit| {
lval a: R|kotlin/Int| = when (R|<local>/e|) {
($subj$ is R|Base.A|) || ($subj$ is R|Base.A.B|) -> {
Int(1)
}
($subj$ is R|C|) -> {
Int(2)
}
}
}