diff --git a/translator/src/org/jetbrains/k2js/translate/expression/foreach/ArrayForTranslator.java b/translator/src/org/jetbrains/k2js/translate/expression/foreach/ArrayForTranslator.java index d7a43c6a2e6..296427f2163 100644 --- a/translator/src/org/jetbrains/k2js/translate/expression/foreach/ArrayForTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/expression/foreach/ArrayForTranslator.java @@ -16,7 +16,6 @@ package org.jetbrains.k2js.translate.expression.foreach; -import 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; @@ -32,6 +31,7 @@ import org.jetbrains.k2js.translate.utils.BindingUtils; import java.util.Collections; import java.util.List; +import static org.jetbrains.k2js.translate.expression.foreach.ForTranslatorUtils.temporariesInitialization; import static org.jetbrains.k2js.translate.utils.DescriptorUtils.getClassDescriptorForType; import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopBody; import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopRange; @@ -58,64 +58,59 @@ public final class ArrayForTranslator extends ForTranslator { } @NotNull - private final TemporaryVariable rangeExpression; + private final TemporaryVariable loopRange; + + @NotNull + private final TemporaryVariable end; + + @NotNull + private final TemporaryVariable index; private ArrayForTranslator(@NotNull JetForExpression forExpression, @NotNull TranslationContext context) { super(forExpression, context); - rangeExpression = context.declareTemporary(Translation.translateAsExpression(getLoopRange(expression), context)); + loopRange = context.declareTemporary(Translation.translateAsExpression(getLoopRange(expression), context)); + JsExpression length = LengthIntrinsic.INSTANCE.apply(loopRange.reference(), Collections.emptyList(), context()); + end = context().declareTemporary(length); + index = context().declareTemporary(program().getNumberLiteral(0)); } @NotNull private JsBlock translate() { - JsExpression length = LengthIntrinsic.INSTANCE.apply(rangeExpression.reference(), Collections.emptyList(), context()); - TemporaryVariable end = context().declareTemporary(length); - List blockStatements = temporariesInitialization(rangeExpression, end); - blockStatements.add(generateForExpression(end)); + List blockStatements = temporariesInitialization(loopRange, end); + blockStatements.add(generateForExpression()); return AstUtil.newBlock(blockStatements); } @NotNull - private JsFor generateForExpression(@NotNull TemporaryVariable end) { + private JsFor generateForExpression() { JsFor result = new JsFor(); - //TODO: make index instance variable - TemporaryVariable indexVar = context().declareTemporary(program().getNumberLiteral(0)); - result.setInitVars(initExpression(indexVar)); - result.setCondition(getCondition(end, indexVar)); - result.setIncrExpr(getIncrExpression(indexVar)); - result.setBody(getBody(indexVar)); + result.setInitVars(initExpression()); + result.setCondition(getCondition()); + result.setIncrExpr(getIncrExpression()); + result.setBody(getBody()); return result; } @NotNull - private JsStatement getBody(@NotNull TemporaryVariable index) { - JsArrayAccess arrayAccess = new JsArrayAccess(rangeExpression.reference(), index.reference()); + private JsStatement getBody() { + JsArrayAccess arrayAccess = new JsArrayAccess(loopRange.reference(), index.reference()); JsStatement currentVar = AstUtil.newVar(parameterName, arrayAccess); JsStatement realBody = Translation.translateAsStatement(getLoopBody(expression), context()); return AstUtil.newBlock(currentVar, realBody); } @NotNull - private JsVars initExpression(TemporaryVariable start) { - return AstUtil.newVar(start.name(), program().getNumberLiteral(0)); + private JsVars initExpression() { + return AstUtil.newVar(index.name(), program().getNumberLiteral(0)); } @NotNull - private JsExpression getCondition(TemporaryVariable end, TemporaryVariable index) { + private JsExpression getCondition() { return AstUtil.notEqual(index.reference(), end.reference()); } @NotNull - private JsExpression getIncrExpression(@NotNull TemporaryVariable index) { + private JsExpression getIncrExpression() { return new JsPrefixOperation(JsUnaryOperator.INC, index.reference()); } - - //TODO: move somewhere util - @NotNull - private List temporariesInitialization(TemporaryVariable... temporaries) { - List result = Lists.newArrayList(); - for (TemporaryVariable temporary : temporaries) { - result.add(temporary.assignmentExpression().makeStmt()); - } - return result; - } } diff --git a/translator/src/org/jetbrains/k2js/translate/expression/foreach/ForTranslator.java b/translator/src/org/jetbrains/k2js/translate/expression/foreach/ForTranslator.java index 77342eb941f..776d8d578e8 100644 --- a/translator/src/org/jetbrains/k2js/translate/expression/foreach/ForTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/expression/foreach/ForTranslator.java @@ -41,12 +41,12 @@ public abstract class ForTranslator extends AbstractTranslator { if (RangeLiteralForTranslator.isApplicable(expression, context)) { return RangeLiteralForTranslator.translate(expression, context); } - if (ArrayForTranslator.isApplicable(expression, context)) { - return ArrayForTranslator.translate(expression, context); - } if (RangeForTranslator.isApplicable(expression, context)) { return RangeForTranslator.translate(expression, context); } + if (ArrayForTranslator.isApplicable(expression, context)) { + return ArrayForTranslator.translate(expression, context); + } return IteratorForTranslator.translate(expression, context); } diff --git a/translator/src/org/jetbrains/k2js/translate/expression/foreach/ForTranslatorUtils.java b/translator/src/org/jetbrains/k2js/translate/expression/foreach/ForTranslatorUtils.java new file mode 100644 index 00000000000..858035bfb31 --- /dev/null +++ b/translator/src/org/jetbrains/k2js/translate/expression/foreach/ForTranslatorUtils.java @@ -0,0 +1,42 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.k2js.translate.expression.foreach; + +import com.google.common.collect.Lists; +import com.google.dart.compiler.backend.js.ast.JsStatement; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.k2js.translate.context.TemporaryVariable; + +import java.util.List; + +/** + * @author Pavel Talanov + */ +public final class ForTranslatorUtils { + + private ForTranslatorUtils() { + } + + @NotNull + public static List temporariesInitialization(@NotNull TemporaryVariable... temporaries) { + List result = Lists.newArrayList(); + for (TemporaryVariable temporary : temporaries) { + result.add(temporary.assignmentExpression().makeStmt()); + } + return result; + } +} diff --git a/translator/src/org/jetbrains/k2js/translate/expression/foreach/IteratorForTranslator.java b/translator/src/org/jetbrains/k2js/translate/expression/foreach/IteratorForTranslator.java index 66be0be538c..f61b93a16ef 100644 --- a/translator/src/org/jetbrains/k2js/translate/expression/foreach/IteratorForTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/expression/foreach/IteratorForTranslator.java @@ -44,23 +44,25 @@ public final class IteratorForTranslator extends ForTranslator { return (new IteratorForTranslator(expression, context).translate()); } + @NotNull + private final TemporaryVariable iterator; + private IteratorForTranslator(@NotNull JetForExpression forExpression, @NotNull TranslationContext context) { super(forExpression, context); + iterator = context().declareTemporary(iteratorMethodInvocation()); } @NotNull private JsBlock translate() { - TemporaryVariable iterator = context().declareTemporary(iteratorMethodInvocation()); - JsBlock bodyBlock = generateCycleBody(parameterName, iterator); - JsWhile cycle = new JsWhile(hasNextMethodInvocation(iterator), bodyBlock); + JsBlock bodyBlock = generateCycleBody(); + JsWhile cycle = new JsWhile(hasNextMethodInvocation(), bodyBlock); return AstUtil.newBlock(iterator.assignmentExpression().makeStmt(), cycle); } @NotNull - private JsBlock generateCycleBody(@NotNull JsName parameterName, @NotNull TemporaryVariable iterator) { + private JsBlock generateCycleBody() { JsBlock cycleBody = new JsBlock(); - JsStatement parameterAssignment = - AstUtil.newVar(parameterName, nextMethodInvocation(iterator)); + JsStatement parameterAssignment = AstUtil.newVar(parameterName, nextMethodInvocation()); JsNode originalBody = Translation.translateExpression(getLoopBody(expression), context().innerBlock(cycleBody)); cycleBody.addStatement(parameterAssignment); cycleBody.addStatement(AstUtil.convertToBlock(originalBody)); @@ -68,13 +70,13 @@ public final class IteratorForTranslator extends ForTranslator { } @NotNull - private JsExpression nextMethodInvocation(@NotNull TemporaryVariable iterator) { + private JsExpression nextMethodInvocation() { FunctionDescriptor nextFunction = getNextFunction(context().bindingContext(), getLoopRange(expression)); return translateMethodInvocation(iterator.reference(), nextFunction); } @NotNull - private JsExpression hasNextMethodInvocation(@NotNull TemporaryVariable iterator) { + private JsExpression hasNextMethodInvocation() { CallableDescriptor hasNextFunction = getHasNextCallable(context().bindingContext(), getLoopRange(expression)); return translateMethodInvocation(iterator.reference(), hasNextFunction); } diff --git a/translator/src/org/jetbrains/k2js/translate/expression/foreach/RangeForTranslator.java b/translator/src/org/jetbrains/k2js/translate/expression/foreach/RangeForTranslator.java index 97730a69f11..9cf83198ba2 100644 --- a/translator/src/org/jetbrains/k2js/translate/expression/foreach/RangeForTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/expression/foreach/RangeForTranslator.java @@ -16,7 +16,6 @@ package org.jetbrains.k2js.translate.expression.foreach; -import 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; @@ -30,6 +29,7 @@ import org.jetbrains.k2js.translate.utils.BindingUtils; import java.util.List; +import static org.jetbrains.k2js.translate.expression.foreach.ForTranslatorUtils.temporariesInitialization; import static org.jetbrains.k2js.translate.utils.DescriptorUtils.getClassDescriptorForType; import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopBody; import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopRange; @@ -55,51 +55,54 @@ public final class RangeForTranslator extends ForTranslator { @NotNull private final TemporaryVariable rangeExpression; + @NotNull + private final TemporaryVariable incrVar; + @NotNull + private final TemporaryVariable start; + @NotNull + private final TemporaryVariable end; private RangeForTranslator(@NotNull JetForExpression forExpression, @NotNull TranslationContext context) { super(forExpression, context); rangeExpression = context.declareTemporary(Translation.translateAsExpression(getLoopRange(expression), context)); - } - - @NotNull - private JsBlock translate() { - //TODO: make fields JsExpression isReversed = callFunction("get_reversed"); JsConditional incrVarValue = new JsConditional(isReversed, program().getNumberLiteral(-1), program().getNumberLiteral(1)); - TemporaryVariable incrVar = context().declareTemporary(incrVarValue); - TemporaryVariable start = context().declareTemporary(callFunction("get_start")); - TemporaryVariable end = context().declareTemporary(new JsBinaryOperation(JsBinaryOperator.ADD, callFunction("get_end"), incrVar.reference())); + incrVar = context().declareTemporary(incrVarValue); + start = context().declareTemporary(callFunction("get_start")); + end = context().declareTemporary(new JsBinaryOperation(JsBinaryOperator.ADD, callFunction("get_end"), incrVar.reference())); + } + + @NotNull + private JsBlock translate() { List blockStatements = temporariesInitialization(rangeExpression, incrVar, start, end); - blockStatements.add(generateForExpression(incrVar, start, end)); + blockStatements.add(generateForExpression()); return AstUtil.newBlock(blockStatements); } @NotNull - private JsFor generateForExpression(@NotNull TemporaryVariable incrVar, - @NotNull TemporaryVariable start, - @NotNull TemporaryVariable end) { + private JsFor generateForExpression() { JsFor result = new JsFor(); - result.setInitVars(initExpression(start, parameterName)); - result.setCondition(getCondition(end, parameterName)); - result.setIncrExpr(getIncrExpression(incrVar, parameterName)); + result.setInitVars(initExpression()); + result.setCondition(getCondition()); + result.setIncrExpr(getIncrExpression()); result.setBody(Translation.translateAsStatement(getLoopBody(expression), context())); return result; } @NotNull - private JsVars initExpression(TemporaryVariable start, JsName parameterName) { + private JsVars initExpression() { return AstUtil.newVar(parameterName, start.reference()); } @NotNull - private JsExpression getCondition(TemporaryVariable end, JsName parameterName) { + private JsExpression getCondition() { return AstUtil.notEqual(parameterName.makeRef(), end.reference()); } @NotNull - private JsExpression getIncrExpression(@NotNull TemporaryVariable incrVar, @NotNull JsName parameterName) { + private JsExpression getIncrExpression() { return new JsBinaryOperation(JsBinaryOperator.ASG_ADD, parameterName.makeRef(), incrVar.reference()); } @@ -114,13 +117,4 @@ public final class RangeForTranslator extends ForTranslator { private JsExpression callFunction(@NotNull String funName) { return AstUtil.newInvocation(getField(funName)); } - - @NotNull - private List temporariesInitialization(TemporaryVariable... temporaries) { - List result = Lists.newArrayList(); - for (TemporaryVariable temporary : temporaries) { - result.add(temporary.assignmentExpression().makeStmt()); - } - return result; - } } diff --git a/translator/src/org/jetbrains/k2js/translate/expression/foreach/RangeLiteralForTranslator.java b/translator/src/org/jetbrains/k2js/translate/expression/foreach/RangeLiteralForTranslator.java index 900e193a372..25cc708664a 100644 --- a/translator/src/org/jetbrains/k2js/translate/expression/foreach/RangeLiteralForTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/expression/foreach/RangeLiteralForTranslator.java @@ -29,6 +29,7 @@ import org.jetbrains.k2js.translate.context.TranslationContext; import java.util.List; +import static org.jetbrains.k2js.translate.expression.foreach.ForTranslatorUtils.temporariesInitialization; import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopRange; import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateLeftExpression; import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateRightExpression; @@ -37,7 +38,7 @@ import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateRight * @author Pavel Talanov */ -// TODO: respect reverse semantics +// TODO: implement reverse semantics public final class RangeLiteralForTranslator extends ForTranslator { @NotNull @@ -108,14 +109,4 @@ public final class RangeLiteralForTranslator extends ForTranslator { private JsExpression getIncrExpression() { return new JsPrefixOperation(JsUnaryOperator.INC, parameterName.makeRef()); } - - //TODO : UTIL!! - @NotNull - private List temporariesInitialization(@NotNull TemporaryVariable... temporaries) { - List result = Lists.newArrayList(); - for (TemporaryVariable temporary : temporaries) { - result.add(temporary.assignmentExpression().makeStmt()); - } - return result; - } }