JS/RTTI: fix compiler crashing when translating expressions like (continue as T)
This commit is contained in:
@@ -132,4 +132,8 @@ public class EvaluationOrderTest extends AbstractExpressionTest {
|
|||||||
public void testLoopWithBreakContinueReturnInCondition() throws Exception {
|
public void testLoopWithBreakContinueReturnInCondition() throws Exception {
|
||||||
checkFooBoxIsOk();
|
checkFooBoxIsOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testCastWithBreakContinueReturn() throws Exception {
|
||||||
|
checkFooBoxIsOk();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
@@ -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.AbstractTranslator;
|
||||||
import org.jetbrains.kotlin.js.translate.general.Translation;
|
import org.jetbrains.kotlin.js.translate.general.Translation;
|
||||||
import org.jetbrains.kotlin.js.translate.utils.BindingUtils;
|
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.lexer.KtTokens;
|
||||||
import org.jetbrains.kotlin.name.Name;
|
import org.jetbrains.kotlin.name.Name;
|
||||||
import org.jetbrains.kotlin.psi.KtBinaryExpressionWithTypeRHS;
|
import org.jetbrains.kotlin.psi.KtBinaryExpressionWithTypeRHS;
|
||||||
@@ -73,6 +74,8 @@ public final class PatternTranslator extends AbstractTranslator {
|
|||||||
assert isCastExpression(expression): "Expected cast expression, got " + expression;
|
assert isCastExpression(expression): "Expected cast expression, got " + expression;
|
||||||
KtExpression left = expression.getLeft();
|
KtExpression left = expression.getLeft();
|
||||||
JsExpression expressionToCast = Translation.translateAsExpression(left, context());
|
JsExpression expressionToCast = Translation.translateAsExpression(left, context());
|
||||||
|
if (JsAstUtils.isEmptyExpression(expressionToCast)) return expressionToCast;
|
||||||
|
|
||||||
TemporaryVariable temporary = context().declareTemporary(expressionToCast);
|
TemporaryVariable temporary = context().declareTemporary(expressionToCast);
|
||||||
|
|
||||||
KtTypeReference typeReference = expression.getRight();
|
KtTypeReference typeReference = expression.getRight();
|
||||||
@@ -105,6 +108,8 @@ public final class PatternTranslator extends AbstractTranslator {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public JsExpression translateIsCheck(@NotNull JsExpression subject, @NotNull KtTypeReference typeReference) {
|
public JsExpression translateIsCheck(@NotNull JsExpression subject, @NotNull KtTypeReference typeReference) {
|
||||||
|
if (JsAstUtils.isEmptyExpression(subject)) return subject;
|
||||||
|
|
||||||
KotlinType type = BindingUtils.getTypeByReference(bindingContext(), typeReference);
|
KotlinType type = BindingUtils.getTypeByReference(bindingContext(), typeReference);
|
||||||
JsExpression checkFunReference = doGetIsTypeCheckCallable(type);
|
JsExpression checkFunReference = doGetIsTypeCheckCallable(type);
|
||||||
boolean isReifiedType = isReifiedTypeParameter(type);
|
boolean isReifiedType = isReifiedTypeParameter(type);
|
||||||
|
|||||||
+120
@@ -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"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user