Cache argument of when expression (should be evaluated only once).
This commit is contained in:
@@ -40,6 +40,10 @@ public final class PatternMatchingTest extends SingleFileTranslationTest {
|
||||
fooBoxTest();
|
||||
}
|
||||
|
||||
public void testWhenEvaluatesArgumentOnlyOnce() throws Exception {
|
||||
fooBoxTest();
|
||||
}
|
||||
|
||||
public void testWhenValue() throws Exception {
|
||||
fooBoxTest();
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.k2js.translate.expression;
|
||||
|
||||
import closurecompiler.internal.com.google.common.collect.Lists;
|
||||
import com.google.dart.compiler.backend.js.ast.*;
|
||||
import com.google.dart.compiler.util.AstUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -47,7 +48,7 @@ public final class WhenTranslator extends AbstractTranslator {
|
||||
@NotNull
|
||||
private final JetWhenExpression whenExpression;
|
||||
@Nullable
|
||||
private final JsExpression expressionToMatch;
|
||||
private final TemporaryVariable expressionToMatch;
|
||||
@NotNull
|
||||
private final TemporaryVariable dummyCounter;
|
||||
@NotNull
|
||||
@@ -58,7 +59,8 @@ public final class WhenTranslator extends AbstractTranslator {
|
||||
private WhenTranslator(@NotNull JetWhenExpression expression, @NotNull TranslationContext context) {
|
||||
super(context);
|
||||
this.whenExpression = expression;
|
||||
this.expressionToMatch = translateExpressionToMatch(whenExpression);
|
||||
JsExpression expressionToMatch = translateExpressionToMatch(whenExpression);
|
||||
this.expressionToMatch = expressionToMatch != null ? context.declareTemporary(expressionToMatch) : null;
|
||||
this.dummyCounter = context.declareTemporary(program().getNumberLiteral(0));
|
||||
this.result = context.declareTemporary(program().getNullLiteral());
|
||||
}
|
||||
@@ -66,8 +68,7 @@ public final class WhenTranslator extends AbstractTranslator {
|
||||
@NotNull
|
||||
JsNode translate() {
|
||||
JsFor resultingFor = generateDummyFor();
|
||||
List<JsStatement> entries = translateEntries();
|
||||
resultingFor.setBody(newBlock(entries));
|
||||
resultingFor.setBody(newBlock(translateEntries()));
|
||||
context().addStatementToCurrentBlock(resultingFor);
|
||||
return result.reference();
|
||||
}
|
||||
@@ -92,12 +93,21 @@ public final class WhenTranslator extends AbstractTranslator {
|
||||
@NotNull
|
||||
private JsFor generateDummyFor() {
|
||||
JsFor result = new JsFor();
|
||||
result.setInitExpr(dummyCounter.assignmentExpression());
|
||||
result.setInitExpr(generateInitExpressions());
|
||||
result.setIncrExpr(generateIncrementStatement());
|
||||
result.setCondition(generateConditionStatement());
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsExpression generateInitExpressions() {
|
||||
List<JsExpression> initExpressions = Lists.newArrayList(dummyCounter.assignmentExpression());
|
||||
if (expressionToMatch != null) {
|
||||
initExpressions.add(expressionToMatch.assignmentExpression());
|
||||
}
|
||||
return newSequence(initExpressions);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsBinaryOperation generateConditionStatement() {
|
||||
JsNumberLiteral entriesNumber = program().getNumberLiteral(whenExpression.getEntries().size());
|
||||
@@ -178,13 +188,18 @@ public final class WhenTranslator extends AbstractTranslator {
|
||||
@NotNull
|
||||
private JsExpression translatePatternCondition(@NotNull JetWhenCondition condition) {
|
||||
JsExpression patternMatchExpression = Translation.patternTranslator(context()).
|
||||
translatePattern(getPattern(condition), expressionToMatch);
|
||||
translatePattern(getPattern(condition), getExpressionToMatch());
|
||||
if (isNegated(condition)) {
|
||||
return negated(patternMatchExpression);
|
||||
}
|
||||
return patternMatchExpression;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private JsExpression getExpressionToMatch() {
|
||||
return expressionToMatch != null ? expressionToMatch.reference() : null;
|
||||
}
|
||||
|
||||
private static boolean isNegated(@NotNull JetWhenCondition condition) {
|
||||
if (condition instanceof JetWhenConditionIsPattern) {
|
||||
return ((JetWhenConditionIsPattern)condition).isNegated();
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package foo
|
||||
|
||||
fun box() : Boolean {
|
||||
var a = 0
|
||||
var i = 0
|
||||
when(i++) {
|
||||
-100 -> a++
|
||||
100 -> a++
|
||||
else -> a++
|
||||
}
|
||||
return (a == 1) && (i == 1)
|
||||
}
|
||||
Reference in New Issue
Block a user