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();
|
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)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user