Cache argument of when expression (should be evaluated only once).

This commit is contained in:
Pavel V. Talanov
2012-07-19 16:20:06 +04:00
parent cd2c55aeca
commit 534bde52f1
3 changed files with 37 additions and 6 deletions
@@ -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)
}