JS/RTTI: fix compiler crashing when translating expressions like (continue as T)

This commit is contained in:
Alexey Andreev
2016-04-28 15:12:01 +03:00
parent 3a87049359
commit 75015f6bfa
3 changed files with 129 additions and 0 deletions
@@ -132,4 +132,8 @@ public class EvaluationOrderTest extends AbstractExpressionTest {
public void testLoopWithBreakContinueReturnInCondition() throws Exception {
checkFooBoxIsOk();
}
public void testCastWithBreakContinueReturn() throws Exception {
checkFooBoxIsOk();
}
}
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.js.translate.context.TranslationContext;
import org.jetbrains.kotlin.js.translate.general.AbstractTranslator;
import org.jetbrains.kotlin.js.translate.general.Translation;
import org.jetbrains.kotlin.js.translate.utils.BindingUtils;
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils;
import org.jetbrains.kotlin.lexer.KtTokens;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.KtBinaryExpressionWithTypeRHS;
@@ -73,6 +74,8 @@ public final class PatternTranslator extends AbstractTranslator {
assert isCastExpression(expression): "Expected cast expression, got " + expression;
KtExpression left = expression.getLeft();
JsExpression expressionToCast = Translation.translateAsExpression(left, context());
if (JsAstUtils.isEmptyExpression(expressionToCast)) return expressionToCast;
TemporaryVariable temporary = context().declareTemporary(expressionToCast);
KtTypeReference typeReference = expression.getRight();
@@ -105,6 +108,8 @@ public final class PatternTranslator extends AbstractTranslator {
@NotNull
public JsExpression translateIsCheck(@NotNull JsExpression subject, @NotNull KtTypeReference typeReference) {
if (JsAstUtils.isEmptyExpression(subject)) return subject;
KotlinType type = BindingUtils.getTypeByReference(bindingContext(), typeReference);
JsExpression checkFunReference = doGetIsTypeCheckCallable(type);
boolean isReifiedType = isReifiedTypeParameter(type);
@@ -0,0 +1,120 @@
package foo
fun castWithReturn(): Int {
return (return 23) as Int
}
fun safeCastWithReturn(): Int? {
return (return 23) as Int?
}
fun isWithReturn(): Int {
return if ((return 23) is Int) 2 else 3
}
fun castWithBreak(): Int {
var result = 23
while (result < 40) {
if ((break as Int) == 0) result += 2 else result += 3
}
return result
}
fun safeCastWithBreak(): Int {
var result = 23
while (result < 40) {
if ((break as Int) == 0) result += 2 else result += 3
}
return result
}
fun isWithBreak(): Int {
var result = 23
while (result < 40) {
if (break is Int) result += 2 else result += 3
}
return result
}
fun castWithContinue(): Int {
var result = 25
while (result in 24..30) {
--result
if ((continue as Int) == 0) result += 2 else result += 3
}
return result
}
fun castNullableWithContinue(): Int {
var result = 25
while (result in 24..30) {
--result
if ((continue as Int?) == 0) result += 2 else result += 3
}
return result
}
fun safeCastWithContinue(): Int {
var result = 25
while (result in 24..30) {
--result
if ((continue as? Int) == 0) result += 2 else result += 3
}
return result
}
fun safeCastNullableWithContinue(): Int {
var result = 25
while (result in 24..30) {
--result
if ((continue as? Int?) == 0) result += 2 else result += 3
}
return result
}
fun isWithContinue(): Int {
var result = 25
while (result in 24..30) {
--result
if (continue is Int) result += 2 else result += 3
}
return result
}
fun isNullableWithContinue(): Int {
var result = 23
while (result in 24..30) {
--result
if (continue is Int?) result += 2 else result += 3
}
return result
}
fun whenWithReturn(): Int {
return when ((return 23) as Int) {
is Int -> 24
else -> 25
}
}
fun box(): String {
assertEquals(23, castWithReturn())
assertEquals(23, safeCastWithReturn())
assertEquals(23, isWithReturn())
assertEquals(23, castWithBreak())
assertEquals(23, safeCastWithBreak())
assertEquals(23, isWithBreak())
assertEquals(23, castWithContinue())
assertEquals(23, safeCastWithContinue())
assertEquals(23, isWithContinue())
assertEquals(23, castNullableWithContinue())
assertEquals(23, safeCastNullableWithContinue())
assertEquals(23, isNullableWithContinue())
assertEquals(23, whenWithReturn())
return "OK"
}