JS: when none of exhaustive when clauses match, generate code that throws exception. See KT-12194

This commit is contained in:
Alexey Andreev
2016-12-27 17:18:47 +03:00
parent 3384c6f603
commit 7f0166623d
7 changed files with 137 additions and 12 deletions
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.types.KotlinType
@@ -141,4 +142,16 @@ object CodegenUtil {
function.returnType != null &&
isReturnTypeOk(function.returnType!!)
}
@JvmStatic
fun BindingContext.isExhaustive(whenExpression: KtWhenExpression, isStatement: Boolean): Boolean {
val slice = if (isStatement && !whenExpression.isUsedAsExpression(this)) {
BindingContext.IMPLICIT_EXHAUSTIVE_WHEN
}
else {
BindingContext.EXHAUSTIVE_WHEN
}
return this[slice, whenExpression] == true
}
}
@@ -4547,7 +4547,8 @@ The "returned" value of try expression with no finally is either the last expres
@Override
public Unit invoke(InstructionAdapter v) {
SwitchCodegen switchCodegen = SwitchCodegenUtil.buildAppropriateSwitchCodegenIfPossible(
expression, isStatement, isExhaustive(expression, isStatement), ExpressionCodegen.this
expression, isStatement, CodegenUtil.isExhaustive(bindingContext, expression, isStatement),
ExpressionCodegen.this
);
if (switchCodegen != null) {
switchCodegen.generate();
@@ -4607,20 +4608,11 @@ The "returned" value of try expression with no finally is either the last expres
});
}
private boolean isExhaustive(@NotNull KtWhenExpression whenExpression, boolean isStatement) {
if (isStatement && !BindingContextUtilsKt.isUsedAsExpression(whenExpression, bindingContext)) {
return Boolean.TRUE.equals(bindingContext.get(BindingContext.IMPLICIT_EXHAUSTIVE_WHEN, whenExpression));
}
else {
return Boolean.TRUE.equals(bindingContext.get(BindingContext.EXHAUSTIVE_WHEN, whenExpression));
}
}
public void putUnitInstanceOntoStackForNonExhaustiveWhen(
@NotNull KtWhenExpression whenExpression,
boolean isStatement
) {
if (isExhaustive(whenExpression, isStatement)) {
if (CodegenUtil.isExhaustive(bindingContext, whenExpression, isStatement)) {
// when() is supposed to be exhaustive
genThrow(v, "kotlin/NoWhenBranchMatchedException", null);
}