Refactored structure of ranges in JS backend.
This commit is contained in:
@@ -101,7 +101,10 @@ public final class StandardClasses {
|
||||
standardClasses.declare().forFQ("jet.Iterator").kotlinClass("Iterator").methods("next").properties("hasNext");
|
||||
|
||||
standardClasses.declare().forFQ("jet.IntRange").kotlinClass("NumberRange")
|
||||
.methods("iterator", "contains").properties("start", "size", "end", "reversed");
|
||||
.methods("iterator", "contains").properties("start", "end", "increment");
|
||||
|
||||
standardClasses.declare().forFQ("jet.IntSequence").kotlinClass("NumberSequence")
|
||||
.methods("iterator", "contains").properties("start", "end", "increment");
|
||||
|
||||
standardClasses.declare().forFQ("jet.Any.toString").kotlinFunction("toString");
|
||||
|
||||
|
||||
+7
-11
@@ -54,28 +54,24 @@ 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;
|
||||
@NotNull
|
||||
private final TemporaryVariable increment;
|
||||
|
||||
private RangeForTranslator(@NotNull JetForExpression forExpression, @NotNull TranslationContext context) {
|
||||
super(forExpression, context);
|
||||
rangeExpression = context.declareTemporary(Translation.translateAsExpression(getLoopRange(expression), context));
|
||||
JsExpression isReversed = callFunction("get_reversed");
|
||||
JsConditional incrVarValue = new JsConditional(isReversed,
|
||||
program().getNumberLiteral(-1),
|
||||
program().getNumberLiteral(1));
|
||||
incrVar = context().declareTemporary(incrVarValue);
|
||||
start = context().declareTemporary(callFunction("get_start"));
|
||||
end = context().declareTemporary(sum(callFunction("get_end"), incrVar.reference()));
|
||||
end = context().declareTemporary(callFunction("get_end"));
|
||||
increment = context().declareTemporary(callFunction("get_increment"));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsBlock translate() {
|
||||
List<JsStatement> blockStatements = Lists.newArrayList();
|
||||
blockStatements.add(temporariesInitialization(rangeExpression, incrVar, start, end).makeStmt());
|
||||
blockStatements.add(temporariesInitialization(rangeExpression, start, end, increment).makeStmt());
|
||||
blockStatements.add(generateForExpression());
|
||||
return new JsBlock(blockStatements);
|
||||
}
|
||||
@@ -94,12 +90,12 @@ public final class RangeForTranslator extends ForTranslator {
|
||||
|
||||
@NotNull
|
||||
private JsExpression getCondition() {
|
||||
return inequality(parameterName.makeRef(), end.reference());
|
||||
return lessThanEq(parameterName.makeRef(), end.reference());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsExpression getIncrExpression() {
|
||||
return addAssign(parameterName.makeRef(), incrVar.reference());
|
||||
return addAssign(parameterName.makeRef(), increment.reference());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+1
-3
@@ -51,12 +51,10 @@ public enum PrimitiveBinaryOperationFIF implements FunctionIntrinsicFactory {
|
||||
assert arguments.size() == 1 : "RangeTo must have one argument.";
|
||||
assert rangeStart != null;
|
||||
JsExpression rangeEnd = arguments.get(0);
|
||||
JsBinaryOperation rangeSize = sum(subtract(rangeEnd, rangeStart),
|
||||
context.program().getNumberLiteral(1));
|
||||
JsNameRef expr = AstUtil.newQualifiedNameRef("Kotlin.NumberRange");
|
||||
HasArguments numberRangeConstructorInvocation = context.isEcma5() ? new JsInvocation(expr) : new JsNew(expr);
|
||||
//TODO: add tests and correct expression for reversed ranges.
|
||||
setArguments(numberRangeConstructorInvocation, rangeStart, rangeSize, /*range is not reversed*/JsLiteral.FALSE);
|
||||
setArguments(numberRangeConstructorInvocation, rangeStart, rangeEnd);
|
||||
return (JsExpression) numberRangeConstructorInvocation;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -115,6 +115,11 @@ public final class JsAstUtils {
|
||||
return new JsBinaryOperation(JsBinaryOperator.REF_NEQ, arg1, arg2);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsBinaryOperation lessThanEq(@NotNull JsExpression arg1, @NotNull JsExpression arg2) {
|
||||
return new JsBinaryOperation(JsBinaryOperator.LTE, arg1, arg2);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsExpression assignment(@NotNull JsExpression left, @NotNull JsExpression right) {
|
||||
return new JsBinaryOperation(JsBinaryOperator.ASG, left, right);
|
||||
|
||||
@@ -63,12 +63,12 @@ var kotlin = {set:function (receiver, key, value) {
|
||||
return args === null || args === undefined ? [] : args.slice();
|
||||
};
|
||||
|
||||
Kotlin.intUpto = function (from, limit) {
|
||||
return Kotlin.$new(Kotlin.NumberRange)(from, limit - from + 1, false);
|
||||
Kotlin.intUpto = function (from, to) {
|
||||
return Kotlin.$new(Kotlin.NumberRange)(from, to);
|
||||
};
|
||||
|
||||
Kotlin.intDownto = function (from, limit) {
|
||||
return Kotlin.$new(Kotlin.NumberRange)(from, from - limit + 1, true);
|
||||
Kotlin.intDownto = function (from, to) {
|
||||
return Kotlin.$new(Kotlin.NumberSequence)(from, to, -1);
|
||||
};
|
||||
|
||||
Kotlin.modules = {};
|
||||
@@ -344,23 +344,17 @@ var kotlin = {set:function (receiver, key, value) {
|
||||
};
|
||||
|
||||
Kotlin.RangeIterator = Kotlin.$createClass(Kotlin.Iterator, {
|
||||
initialize: function (start, count, reversed) {
|
||||
initialize: function (start, end, increment) {
|
||||
this.$start = start;
|
||||
this.$count = count;
|
||||
this.$reversed = reversed;
|
||||
this.$i = this.get_start();
|
||||
this.$end = end;
|
||||
this.$increment = increment;
|
||||
this.$i = start;
|
||||
},
|
||||
get_start: function () {
|
||||
return this.$start;
|
||||
},
|
||||
get_count: function () {
|
||||
return this.$count;
|
||||
},
|
||||
set_count: function (tmp$0) {
|
||||
this.$count = tmp$0;
|
||||
},
|
||||
get_reversed: function () {
|
||||
return this.$reversed;
|
||||
get_end: function () {
|
||||
return this.$end;
|
||||
},
|
||||
get_i: function () {
|
||||
return this.$i;
|
||||
@@ -369,49 +363,54 @@ var kotlin = {set:function (receiver, key, value) {
|
||||
this.$i = tmp$0;
|
||||
},
|
||||
next: function () {
|
||||
this.set_count(this.get_count() - 1);
|
||||
if (this.get_reversed()) {
|
||||
this.set_i(this.get_i() - 1);
|
||||
return this.get_i() + 1;
|
||||
}
|
||||
else {
|
||||
this.set_i(this.get_i() + 1);
|
||||
return this.get_i() - 1;
|
||||
}
|
||||
var value = this.$i;
|
||||
this.set_i(this.$i + this.$increment)
|
||||
return value;
|
||||
},
|
||||
get_hasNext: function () {
|
||||
return this.get_count() > 0;
|
||||
return this.$increment > 0 ? this.$next <= this.$end : this.$next >= this.$end;
|
||||
}
|
||||
});
|
||||
|
||||
Kotlin.NumberRange = Kotlin.$createClass({
|
||||
initialize: function (start, size, reversed) {
|
||||
initialize: function (start, end) {
|
||||
this.$start = start;
|
||||
this.$size = size;
|
||||
this.$reversed = reversed;
|
||||
this.$end = end;
|
||||
},
|
||||
get_start: function () {
|
||||
return this.$start;
|
||||
},
|
||||
get_size: function () {
|
||||
return this.$size;
|
||||
},
|
||||
get_reversed: function () {
|
||||
return this.$reversed;
|
||||
},
|
||||
get_end: function () {
|
||||
return this.get_reversed() ? this.get_start() - this.get_size() + 1 : this.get_start() + this.get_size() - 1;
|
||||
return this.$end;
|
||||
},
|
||||
get_increment: function () {
|
||||
return 1;
|
||||
},
|
||||
contains: function (number) {
|
||||
if (this.get_reversed()) {
|
||||
return number <= this.get_start() && number > this.get_start() - this.get_size();
|
||||
}
|
||||
else {
|
||||
return number >= this.get_start() && number < this.get_start() + this.get_size();
|
||||
}
|
||||
return this.$start <= number && number <= this.$end;
|
||||
},
|
||||
iterator: function () {
|
||||
return Kotlin.$new(Kotlin.RangeIterator)(this.get_start(), this.get_size(), this.get_reversed());
|
||||
return Kotlin.$new(Kotlin.RangeIterator)(this.get_start(), this.get_end());
|
||||
}
|
||||
});
|
||||
|
||||
Kotlin.NumberSequence = Kotlin.$createClass({
|
||||
initialize: function (start, end, increment) {
|
||||
this.$start = start;
|
||||
this.$end = end;
|
||||
this.$increment = increment;
|
||||
},
|
||||
get_start: function () {
|
||||
return this.$start;
|
||||
},
|
||||
get_end: function () {
|
||||
return this.$end;
|
||||
},
|
||||
get_increment: function () {
|
||||
return this.$increment;
|
||||
},
|
||||
iterator: function () {
|
||||
return Kotlin.$new(Kotlin.RangeIterator)(this.get_start(), this.get_end(), this.get_increment());
|
||||
}
|
||||
});
|
||||
|
||||
@@ -483,7 +482,7 @@ var kotlin = {set:function (receiver, key, value) {
|
||||
};
|
||||
|
||||
Kotlin.arrayIndices = function (arr) {
|
||||
return Kotlin.$new(Kotlin.NumberRange)(0, arr.length);
|
||||
return Kotlin.$new(Kotlin.NumberRange)(0, arr.length - 1);
|
||||
};
|
||||
|
||||
Kotlin.arrayIterator = function (array) {
|
||||
|
||||
Reference in New Issue
Block a user