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(); fooBoxTest();
} }
public void testWhenEvaluatesArgumentOnlyOnce() throws Exception {
fooBoxTest();
}
public void testWhenValue() throws Exception { public void testWhenValue() throws Exception {
fooBoxTest(); fooBoxTest();
} }
@@ -16,6 +16,7 @@
package org.jetbrains.k2js.translate.expression; 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.backend.js.ast.*;
import com.google.dart.compiler.util.AstUtil; import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -47,7 +48,7 @@ public final class WhenTranslator extends AbstractTranslator {
@NotNull @NotNull
private final JetWhenExpression whenExpression; private final JetWhenExpression whenExpression;
@Nullable @Nullable
private final JsExpression expressionToMatch; private final TemporaryVariable expressionToMatch;
@NotNull @NotNull
private final TemporaryVariable dummyCounter; private final TemporaryVariable dummyCounter;
@NotNull @NotNull
@@ -58,7 +59,8 @@ public final class WhenTranslator extends AbstractTranslator {
private WhenTranslator(@NotNull JetWhenExpression expression, @NotNull TranslationContext context) { private WhenTranslator(@NotNull JetWhenExpression expression, @NotNull TranslationContext context) {
super(context); super(context);
this.whenExpression = expression; 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.dummyCounter = context.declareTemporary(program().getNumberLiteral(0));
this.result = context.declareTemporary(program().getNullLiteral()); this.result = context.declareTemporary(program().getNullLiteral());
} }
@@ -66,8 +68,7 @@ public final class WhenTranslator extends AbstractTranslator {
@NotNull @NotNull
JsNode translate() { JsNode translate() {
JsFor resultingFor = generateDummyFor(); JsFor resultingFor = generateDummyFor();
List<JsStatement> entries = translateEntries(); resultingFor.setBody(newBlock(translateEntries()));
resultingFor.setBody(newBlock(entries));
context().addStatementToCurrentBlock(resultingFor); context().addStatementToCurrentBlock(resultingFor);
return result.reference(); return result.reference();
} }
@@ -92,12 +93,21 @@ public final class WhenTranslator extends AbstractTranslator {
@NotNull @NotNull
private JsFor generateDummyFor() { private JsFor generateDummyFor() {
JsFor result = new JsFor(); JsFor result = new JsFor();
result.setInitExpr(dummyCounter.assignmentExpression()); result.setInitExpr(generateInitExpressions());
result.setIncrExpr(generateIncrementStatement()); result.setIncrExpr(generateIncrementStatement());
result.setCondition(generateConditionStatement()); result.setCondition(generateConditionStatement());
return result; return result;
} }
@NotNull
private JsExpression generateInitExpressions() {
List<JsExpression> initExpressions = Lists.newArrayList(dummyCounter.assignmentExpression());
if (expressionToMatch != null) {
initExpressions.add(expressionToMatch.assignmentExpression());
}
return newSequence(initExpressions);
}
@NotNull @NotNull
private JsBinaryOperation generateConditionStatement() { private JsBinaryOperation generateConditionStatement() {
JsNumberLiteral entriesNumber = program().getNumberLiteral(whenExpression.getEntries().size()); JsNumberLiteral entriesNumber = program().getNumberLiteral(whenExpression.getEntries().size());
@@ -178,13 +188,18 @@ public final class WhenTranslator extends AbstractTranslator {
@NotNull @NotNull
private JsExpression translatePatternCondition(@NotNull JetWhenCondition condition) { private JsExpression translatePatternCondition(@NotNull JetWhenCondition condition) {
JsExpression patternMatchExpression = Translation.patternTranslator(context()). JsExpression patternMatchExpression = Translation.patternTranslator(context()).
translatePattern(getPattern(condition), expressionToMatch); translatePattern(getPattern(condition), getExpressionToMatch());
if (isNegated(condition)) { if (isNegated(condition)) {
return negated(patternMatchExpression); return negated(patternMatchExpression);
} }
return patternMatchExpression; return patternMatchExpression;
} }
@Nullable
private JsExpression getExpressionToMatch() {
return expressionToMatch != null ? expressionToMatch.reference() : null;
}
private static boolean isNegated(@NotNull JetWhenCondition condition) { private static boolean isNegated(@NotNull JetWhenCondition condition) {
if (condition instanceof JetWhenConditionIsPattern) { if (condition instanceof JetWhenConditionIsPattern) {
return ((JetWhenConditionIsPattern)condition).isNegated(); 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)
}