added dirty implementation for iterating over range literals
This commit is contained in:
+1
-1
@@ -89,7 +89,7 @@ public final class ArrayForTranslator extends ForTranslator {
|
|||||||
@NotNull
|
@NotNull
|
||||||
private JsStatement getBody(@NotNull TemporaryVariable index) {
|
private JsStatement getBody(@NotNull TemporaryVariable index) {
|
||||||
JsArrayAccess arrayAccess = new JsArrayAccess(rangeExpression.reference(), index.reference());
|
JsArrayAccess arrayAccess = new JsArrayAccess(rangeExpression.reference(), index.reference());
|
||||||
JsStatement currentVar = AstUtil.newVar(declareParameter(), arrayAccess);
|
JsStatement currentVar = AstUtil.newVar(parameterName, arrayAccess);
|
||||||
JsStatement realBody = Translation.translateAsStatement(getLoopBody(expression), context());
|
JsStatement realBody = Translation.translateAsStatement(getLoopBody(expression), context());
|
||||||
return AstUtil.newBlock(currentVar, realBody);
|
return AstUtil.newBlock(currentVar, realBody);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,17 +23,24 @@ import org.jetbrains.jet.lang.psi.JetForExpression;
|
|||||||
import org.jetbrains.jet.lang.psi.JetParameter;
|
import org.jetbrains.jet.lang.psi.JetParameter;
|
||||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||||
import org.jetbrains.k2js.translate.general.AbstractTranslator;
|
import org.jetbrains.k2js.translate.general.AbstractTranslator;
|
||||||
|
import org.jetbrains.k2js.translate.general.Translation;
|
||||||
|
|
||||||
|
import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopBody;
|
||||||
import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopParameter;
|
import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopParameter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Pavel Talanov
|
* @author Pavel Talanov
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
//TODO: create util class for managing stuff like binary operations
|
||||||
public abstract class ForTranslator extends AbstractTranslator {
|
public abstract class ForTranslator extends AbstractTranslator {
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static JsStatement translate(@NotNull JetForExpression expression,
|
public static JsStatement translate(@NotNull JetForExpression expression,
|
||||||
@NotNull TranslationContext context) {
|
@NotNull TranslationContext context) {
|
||||||
|
if (RangeLiteralForTranslator.isApplicable(expression, context)) {
|
||||||
|
return RangeLiteralForTranslator.translate(expression, context);
|
||||||
|
}
|
||||||
if (ArrayForTranslator.isApplicable(expression, context)) {
|
if (ArrayForTranslator.isApplicable(expression, context)) {
|
||||||
return ArrayForTranslator.translate(expression, context);
|
return ArrayForTranslator.translate(expression, context);
|
||||||
}
|
}
|
||||||
@@ -45,15 +52,26 @@ public abstract class ForTranslator extends AbstractTranslator {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
protected final JetForExpression expression;
|
protected final JetForExpression expression;
|
||||||
|
@NotNull
|
||||||
|
protected final JsName parameterName;
|
||||||
|
|
||||||
protected ForTranslator(@NotNull JetForExpression forExpression, @NotNull TranslationContext context) {
|
protected ForTranslator(@NotNull JetForExpression forExpression, @NotNull TranslationContext context) {
|
||||||
super(context);
|
super(context);
|
||||||
this.expression = forExpression;
|
this.expression = forExpression;
|
||||||
|
this.parameterName = declareParameter();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
protected JsName declareParameter() {
|
private JsName declareParameter() {
|
||||||
JetParameter loopParameter = getLoopParameter(expression);
|
JetParameter loopParameter = getLoopParameter(expression);
|
||||||
return context().getNameForElement(loopParameter);
|
return context().getNameForElement(loopParameter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: look for should-be-usages
|
||||||
|
@NotNull
|
||||||
|
protected JsStatement translateOriginalBodyExpression() {
|
||||||
|
return Translation.translateAsStatement(getLoopBody(expression), context());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
-1
@@ -50,7 +50,6 @@ public final class IteratorForTranslator extends ForTranslator {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JsBlock translate() {
|
private JsBlock translate() {
|
||||||
JsName parameterName = declareParameter();
|
|
||||||
TemporaryVariable iterator = context().declareTemporary(iteratorMethodInvocation());
|
TemporaryVariable iterator = context().declareTemporary(iteratorMethodInvocation());
|
||||||
JsBlock bodyBlock = generateCycleBody(parameterName, iterator);
|
JsBlock bodyBlock = generateCycleBody(parameterName, iterator);
|
||||||
JsWhile cycle = new JsWhile(hasNextMethodInvocation(iterator), bodyBlock);
|
JsWhile cycle = new JsWhile(hasNextMethodInvocation(iterator), bodyBlock);
|
||||||
|
|||||||
@@ -81,7 +81,6 @@ public final class RangeForTranslator extends ForTranslator {
|
|||||||
@NotNull TemporaryVariable start,
|
@NotNull TemporaryVariable start,
|
||||||
@NotNull TemporaryVariable end) {
|
@NotNull TemporaryVariable end) {
|
||||||
JsFor result = new JsFor();
|
JsFor result = new JsFor();
|
||||||
JsName parameterName = declareParameter();
|
|
||||||
result.setInitVars(initExpression(start, parameterName));
|
result.setInitVars(initExpression(start, parameterName));
|
||||||
result.setCondition(getCondition(end, parameterName));
|
result.setCondition(getCondition(end, parameterName));
|
||||||
result.setIncrExpr(getIncrExpression(incrVar, parameterName));
|
result.setIncrExpr(getIncrExpression(incrVar, parameterName));
|
||||||
|
|||||||
+121
@@ -0,0 +1,121 @@
|
|||||||
|
/*
|
||||||
|
* 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.*;
|
||||||
|
import com.google.dart.compiler.util.AstUtil;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetBinaryExpression;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetForExpression;
|
||||||
|
import org.jetbrains.jet.lexer.JetTokens;
|
||||||
|
import org.jetbrains.k2js.translate.context.TemporaryVariable;
|
||||||
|
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Pavel Talanov
|
||||||
|
*/
|
||||||
|
|
||||||
|
// TODO: respect reverse semantics
|
||||||
|
public final class RangeLiteralForTranslator extends ForTranslator {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static JsStatement translate(@NotNull JetForExpression expression,
|
||||||
|
@NotNull TranslationContext context) {
|
||||||
|
return (new RangeLiteralForTranslator(expression, context).translate());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isApplicable(@NotNull JetForExpression expression,
|
||||||
|
@NotNull TranslationContext context) {
|
||||||
|
JetExpression loopRange = getLoopRange(expression);
|
||||||
|
if (!(loopRange instanceof JetBinaryExpression)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
boolean isRangeToOperation = ((JetBinaryExpression) loopRange).getOperationToken() == JetTokens.RANGE;
|
||||||
|
return isRangeToOperation && RangeForTranslator.isApplicable(expression, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private final TemporaryVariable rangeStart;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private final TemporaryVariable rangeEnd;
|
||||||
|
|
||||||
|
private RangeLiteralForTranslator(@NotNull JetForExpression forExpression, @NotNull TranslationContext context) {
|
||||||
|
super(forExpression, context);
|
||||||
|
JetExpression loopRange = getLoopRange(expression);
|
||||||
|
assert loopRange instanceof JetBinaryExpression;
|
||||||
|
JetBinaryExpression loopRangeAsBinary = ((JetBinaryExpression) loopRange);
|
||||||
|
rangeStart = context.declareTemporary(translateLeftExpression(context, loopRangeAsBinary));
|
||||||
|
rangeEnd = context.declareTemporary(getRangeEnd(loopRangeAsBinary));
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private JsExpression getRangeEnd(@NotNull JetBinaryExpression loopRangeAsBinary) {
|
||||||
|
JsExpression rightExpression = translateRightExpression(context(), loopRangeAsBinary);
|
||||||
|
return new JsBinaryOperation(JsBinaryOperator.ADD, rightExpression, program().getNumberLiteral(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private JsBlock translate() {
|
||||||
|
List<JsStatement> blockStatements = temporariesInitialization(rangeEnd, rangeStart);
|
||||||
|
blockStatements.add(generateForExpression());
|
||||||
|
return AstUtil.newBlock(blockStatements);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private JsFor generateForExpression() {
|
||||||
|
JsFor result = new JsFor();
|
||||||
|
result.setInitVars(initExpression());
|
||||||
|
result.setCondition(getCondition());
|
||||||
|
result.setIncrExpr(getIncrExpression());
|
||||||
|
result.setBody(translateOriginalBodyExpression());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private JsVars initExpression() {
|
||||||
|
return AstUtil.newVar(parameterName, rangeStart.reference());
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private JsExpression getCondition() {
|
||||||
|
return AstUtil.notEqual(parameterName.makeRef(), rangeEnd.reference());
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private JsExpression getIncrExpression() {
|
||||||
|
return new JsPrefixOperation(JsUnaryOperator.INC, parameterName.makeRef());
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO : UTIL!!
|
||||||
|
@NotNull
|
||||||
|
private List<JsStatement> temporariesInitialization(@NotNull TemporaryVariable... temporaries) {
|
||||||
|
List<JsStatement> result = Lists.newArrayList();
|
||||||
|
for (TemporaryVariable temporary : temporaries) {
|
||||||
|
result.add(temporary.assignmentExpression().makeStmt());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
import js.*
|
||||||
|
|
||||||
|
fun box() : Boolean {
|
||||||
|
|
||||||
|
var d = 0
|
||||||
|
for (i in 1..6) {
|
||||||
|
d += i
|
||||||
|
}
|
||||||
|
if (d != 21) return false;
|
||||||
|
|
||||||
|
for (x in 100..199) {
|
||||||
|
d += 1
|
||||||
|
}
|
||||||
|
if (d != 121) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (y in 1..1) {
|
||||||
|
d = 100
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d != 100) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (c in 100..100) {
|
||||||
|
d += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d != 101) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
box()
|
||||||
|
}
|
||||||
@@ -43,4 +43,7 @@ public final class RangeTest extends TranslationTest {
|
|||||||
testFooBoxIsTrue("intInRange.kt");
|
testFooBoxIsTrue("intInRange.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testIteratingOverRanges() throws Exception {
|
||||||
|
testFooBoxIsTrue("iteratingOverRanges.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user