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