JS backend: fix compiler crash on for with empty body
This commit is contained in:
@@ -57,4 +57,12 @@ public final class ForeachTest extends AbstractExpressionTest {
|
|||||||
public void testLabeledForWithWhile() throws Exception {
|
public void testLabeledForWithWhile() throws Exception {
|
||||||
checkFooBoxIsOk();
|
checkFooBoxIsOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testForWithEmptyBody() throws Exception {
|
||||||
|
checkFooBoxIsOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testForWithSideEffectImElementAccessAndWithEmptyBody() throws Exception {
|
||||||
|
checkFooBoxIsOk();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ import org.jetbrains.kotlin.js.translate.utils.BindingUtils.getIteratorFunction
|
|||||||
import org.jetbrains.kotlin.js.translate.utils.BindingUtils.getNextFunction
|
import org.jetbrains.kotlin.js.translate.utils.BindingUtils.getNextFunction
|
||||||
import org.jetbrains.kotlin.js.translate.utils.BindingUtils.getTypeForExpression
|
import org.jetbrains.kotlin.js.translate.utils.BindingUtils.getTypeForExpression
|
||||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils.*
|
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils.*
|
||||||
import org.jetbrains.kotlin.js.translate.utils.PsiUtils.getLoopBody
|
|
||||||
import org.jetbrains.kotlin.js.translate.utils.PsiUtils.getLoopParameter
|
import org.jetbrains.kotlin.js.translate.utils.PsiUtils.getLoopParameter
|
||||||
import org.jetbrains.kotlin.js.translate.utils.PsiUtils.getLoopRange
|
import org.jetbrains.kotlin.js.translate.utils.PsiUtils.getLoopRange
|
||||||
import org.jetbrains.kotlin.js.translate.utils.TemporariesUtils.temporariesInitialization
|
import org.jetbrains.kotlin.js.translate.utils.TemporariesUtils.temporariesInitialization
|
||||||
@@ -127,8 +126,8 @@ public fun translateForExpression(expression: JetForExpression, context: Transla
|
|||||||
|
|
||||||
val parameterName: JsName = declareParameter()
|
val parameterName: JsName = declareParameter()
|
||||||
|
|
||||||
fun translateBody(itemValue: JsExpression?): JsStatement {
|
fun translateBody(itemValue: JsExpression?): JsStatement? {
|
||||||
val realBody = Translation.translateAsStatementAndMergeInBlockIfNeeded(getLoopBody(expression), context)
|
val realBody = expression.getBody()?.let { Translation.translateAsStatementAndMergeInBlockIfNeeded(it, context) }
|
||||||
if (itemValue == null && multiParameter == null) {
|
if (itemValue == null && multiParameter == null) {
|
||||||
return realBody
|
return realBody
|
||||||
}
|
}
|
||||||
@@ -138,6 +137,9 @@ public fun translateForExpression(expression: JetForExpression, context: Transla
|
|||||||
newVar(parameterName, itemValue)
|
newVar(parameterName, itemValue)
|
||||||
else
|
else
|
||||||
MultiDeclarationTranslator.translate(multiParameter, parameterName, itemValue, context)
|
MultiDeclarationTranslator.translate(multiParameter, parameterName, itemValue, context)
|
||||||
|
|
||||||
|
if (realBody == null) return JsBlock(currentVarInit)
|
||||||
|
|
||||||
val block = convertToBlock(realBody)
|
val block = convertToBlock(realBody)
|
||||||
block.getStatements().add(0, currentVarInit)
|
block.getStatements().add(0, currentVarInit)
|
||||||
return block
|
return block
|
||||||
@@ -230,7 +232,9 @@ public fun translateForExpression(expression: JetForExpression, context: Transla
|
|||||||
}
|
}
|
||||||
|
|
||||||
context.addStatementToCurrentBlock(iteratorVar.assignmentExpression().makeStmt())
|
context.addStatementToCurrentBlock(iteratorVar.assignmentExpression().makeStmt())
|
||||||
return JsWhile(hasNextMethodInvocation(), translateBody(nextMethodInvocation()))
|
val nextInvoke = nextMethodInvocation()
|
||||||
|
val body = translateBody(nextInvoke)
|
||||||
|
return JsWhile(hasNextMethodInvocation(), body ?: nextInvoke.makeStmt())
|
||||||
}
|
}
|
||||||
|
|
||||||
return when {
|
return when {
|
||||||
|
|||||||
@@ -111,13 +111,6 @@ public final class PsiUtils {
|
|||||||
return (binaryExpression.getOperationToken() == JetTokens.IN_KEYWORD);
|
return (binaryExpression.getOperationToken() == JetTokens.IN_KEYWORD);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public static JetExpression getLoopBody(@NotNull JetLoopExpression expression) {
|
|
||||||
JetExpression body = expression.getBody();
|
|
||||||
assert body != null : "Loops cannot have null bodies.";
|
|
||||||
return body;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static JetParameter getLoopParameter(@NotNull JetForExpression expression) {
|
public static JetParameter getLoopParameter(@NotNull JetForExpression expression) {
|
||||||
return expression.getLoopParameter();
|
return expression.getLoopParameter();
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
for (i in 0..5);
|
||||||
|
|
||||||
|
val r = 0..5
|
||||||
|
for (i in r);
|
||||||
|
|
||||||
|
for (i in arrayOf(1, 2, 3));
|
||||||
|
|
||||||
|
for (i in arrayOf(1, 2, 3).asList());
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
Vendored
+45
@@ -0,0 +1,45 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
var log = ""
|
||||||
|
|
||||||
|
class T(val id: Int) {
|
||||||
|
fun component1(): Int {
|
||||||
|
log += "($id).component1();"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
fun component2(): String {
|
||||||
|
log += "($id).component2();"
|
||||||
|
return "1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class C {
|
||||||
|
fun iterator(): Iterator<T> = object: Iterator<T> {
|
||||||
|
var i = 0
|
||||||
|
var data = arrayOf(T(3), T(1), T(2))
|
||||||
|
override fun hasNext(): Boolean {
|
||||||
|
log += "C.hasNext();"
|
||||||
|
return i < data.size()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun next(): T {
|
||||||
|
log += "C.next();"
|
||||||
|
return data[i++]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
for ((a, b) in arrayOf(T(3), T(1), T(2)));
|
||||||
|
assertEquals("(3).component1();(3).component2();(1).component1();(1).component2();(2).component1();(2).component2();", log)
|
||||||
|
|
||||||
|
|
||||||
|
log = ""
|
||||||
|
for ((a, b) in C());
|
||||||
|
assertEquals("C.hasNext();C.next();(3).component1();(3).component2();C.hasNext();C.next();" +
|
||||||
|
"(1).component1();(1).component2();C.hasNext();C.next();" +
|
||||||
|
"(2).component1();(2).component2();C.hasNext();", log)
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user