range standard implementation added. tests added.
This commit is contained in:
@@ -317,11 +317,11 @@ public class AstUtil {
|
||||
}
|
||||
|
||||
public static JsBinaryOperation equals(JsExpression arg1, JsExpression arg2) {
|
||||
return new JsBinaryOperation(JsBinaryOperator.REF_EQ, arg1, arg2);
|
||||
return new JsBinaryOperation(JsBinaryOperator.EQ, arg1, arg2);
|
||||
}
|
||||
|
||||
public static JsBinaryOperation notEqual(JsExpression arg1, JsExpression arg2) {
|
||||
return new JsBinaryOperation(JsBinaryOperator.REF_NEQ, arg1, arg2);
|
||||
return new JsBinaryOperation(JsBinaryOperator.NEQ, arg1, arg2);
|
||||
}
|
||||
|
||||
public static JsExpression equalsTrue(JsExpression expression, JsProgram program) {
|
||||
|
||||
@@ -28,13 +28,23 @@ public final class StandardClasses {
|
||||
StandardClasses standardClasses = new StandardClasses(kotlinObjectScope);
|
||||
declareArray(standardClasses, standardLibrary);
|
||||
declareIterator(standardClasses, standardLibrary);
|
||||
declareRange(standardClasses, standardLibrary);
|
||||
declareJavaArrayList(standardClasses);
|
||||
declareJavaSystem(standardClasses);
|
||||
declareInteger(standardClasses);
|
||||
declareJavaInteger(standardClasses);
|
||||
return standardClasses;
|
||||
}
|
||||
|
||||
private static void declareInteger(@NotNull StandardClasses standardClasses) {
|
||||
//TODO: duplication
|
||||
private static void declareRange(@NotNull StandardClasses standardClasses, @NotNull JetStandardLibrary standardLibrary) {
|
||||
String intRangeFQName = "jet.IntRange";
|
||||
standardClasses.declareStandardTopLevelObject(intRangeFQName, "NumberRange");
|
||||
standardClasses.declareStandardInnerDeclaration(intRangeFQName, "<init>", "NumberRange");
|
||||
declareMethods(standardClasses, intRangeFQName, "iterator", "contains");
|
||||
declareProperties(standardClasses, intRangeFQName, "start", "size", "end", "reversed");
|
||||
}
|
||||
|
||||
private static void declareJavaInteger(@NotNull StandardClasses standardClasses) {
|
||||
String integerFQName = "<java_root>.java.lang.Integer";
|
||||
standardClasses.declareStandardTopLevelObject(integerFQName, "Integer");
|
||||
declareMethods(standardClasses, integerFQName, "parseInt");
|
||||
@@ -87,6 +97,15 @@ public final class StandardClasses {
|
||||
}
|
||||
}
|
||||
|
||||
private static void declareProperties(@NotNull StandardClasses standardClasses,
|
||||
@NotNull String classFQName,
|
||||
@NotNull String... propertyNames) {
|
||||
for (String propertyName : propertyNames) {
|
||||
standardClasses.declareStandardInnerDeclaration(classFQName,
|
||||
propertyName, Namer.getNameForGetter(propertyName));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
private final JsScope kotlinScope;
|
||||
|
||||
@@ -11,7 +11,6 @@ import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.general.AbstractTranslator;
|
||||
import org.jetbrains.k2js.translate.reference.AccessTranslator;
|
||||
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.isStatement;
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.isVariableReassignment;
|
||||
import static org.jetbrains.k2js.translate.utils.PsiUtils.*;
|
||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.isIntrinsicOperation;
|
||||
@@ -65,7 +64,9 @@ public abstract class IncrementTranslator extends AbstractTranslator {
|
||||
}
|
||||
|
||||
private boolean returnValueIgnored() {
|
||||
return isStatement(context().bindingContext(), expression);
|
||||
//TODO: it's a hack but for now there is now legal way to know whether expression is statement or not.
|
||||
return false;
|
||||
//return isStatement(context().bindingContext(), expression);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -115,6 +115,7 @@ public final class BindingUtils {
|
||||
Boolean isStatement = context.get(BindingContext.STATEMENT, expression);
|
||||
assert isStatement != null : "Invalid behaviour of get(BindingContext.STATEMENT)";
|
||||
return isStatement;
|
||||
// return IsStatement.isStatement(expression);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
package org.jetbrains.k2js.translate.utils;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
|
||||
/**
|
||||
* @author Talanov Pavel
|
||||
*/
|
||||
@SuppressWarnings("NullableProblems")
|
||||
public final class IsStatement {
|
||||
|
||||
private IsStatement() {
|
||||
}
|
||||
|
||||
private static IsStatementVisitor visitor = new IsStatementVisitor();
|
||||
|
||||
public static boolean isStatement(@NotNull JetExpression expression) {
|
||||
return (expression.accept(visitor, null));
|
||||
}
|
||||
|
||||
private static final class IsStatementVisitor extends JetVisitor<Boolean, Void> {
|
||||
|
||||
@NotNull
|
||||
private Boolean visitParent(@NotNull JetElement element) {
|
||||
PsiElement parent = element.getParent();
|
||||
assert parent != null : "Cannot visit top level expressions.";
|
||||
assert parent instanceof JetElement : "Elements of Kotlin PSI must be instances of JetElement";
|
||||
return ((JetElement) parent).accept(this, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Boolean visitJetElement(@NotNull JetElement element, @Nullable Void nothing) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Boolean visitBlockExpression(@NotNull JetBlockExpression expression, @Nullable Void nothing) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Boolean visitWhenExpression(@NotNull JetWhenExpression expression, @Nullable Void nothing) {
|
||||
return visitParent(expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Boolean visitIfExpression(@NotNull JetIfExpression expression, @Nullable Void nothing) {
|
||||
return visitParent(expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Boolean visitWhenEntry(@NotNull JetWhenEntry expression, @Nullable Void nothing) {
|
||||
return visitParent(expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Boolean visitWhenCondition(@NotNull JetWhenCondition expression, @Nullable Void nothing) {
|
||||
return visitParent(expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Boolean visitContainerNode(@NotNull JetContainerNode expression, @Nullable Void nothing) {
|
||||
return visitParent(expression);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,4 +20,10 @@ public class MiscTest extends AbstractExpressionTest {
|
||||
public void namespaceProperties() throws Exception {
|
||||
testFunctionOutput("localProperty.jet", "foo", "box", 50);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void intRange() throws Exception {
|
||||
// checkOutput("intRange.kt", " ");
|
||||
testFooBoxIsTrue("intRange.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.jetbrains.k2js.test;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author Talanov Pavel
|
||||
*/
|
||||
public final class RangeTest extends TranslationTest {
|
||||
|
||||
final private static String MAIN = "range/";
|
||||
|
||||
@Override
|
||||
protected String mainDirectory() {
|
||||
return MAIN;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void explicitRange() throws Exception {
|
||||
testFooBoxIsTrue("explicitRange.kt");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -2,8 +2,6 @@ package org.jetbrains.k2js.test;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @author Talanov Pavel
|
||||
*/
|
||||
@@ -16,12 +14,6 @@ public final class SystemTest extends JavaClassesTest {
|
||||
return MAIN;
|
||||
}
|
||||
|
||||
public void checkOutput(String filename, String expectedResult, String... args) throws Exception {
|
||||
translateFile(filename);
|
||||
runRhinoTest(generateFilenameList(getOutputFilePath(filename)),
|
||||
new RhinoSystemOutputChecker(expectedResult, Arrays.asList(args)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void systemPrint() throws Exception {
|
||||
checkOutput("systemPrint.kt", "Hello, world!");
|
||||
|
||||
@@ -105,4 +105,10 @@ public abstract class TranslationTest {
|
||||
testFunctionOutput(filename, "foo", "box", "OK");
|
||||
}
|
||||
|
||||
protected void checkOutput(String filename, String expectedResult, String... args) throws Exception {
|
||||
translateFile(filename);
|
||||
runRhinoTest(generateFilenameList(getOutputFilePath(filename)),
|
||||
new RhinoSystemOutputChecker(expectedResult, Arrays.asList(args)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
namespace foo
|
||||
|
||||
class RangeIterator(val start : Int, var count : Int, val reversed : Boolean) {
|
||||
|
||||
fun next() : Int {
|
||||
--count
|
||||
return start + if (reversed) -count else count;
|
||||
}
|
||||
|
||||
|
||||
fun hasNext() = (count > 0);
|
||||
}
|
||||
|
||||
class NumberRange(val start : Int, val size : Int, val reversed : Boolean) {
|
||||
|
||||
val end : Int
|
||||
get() = start + size
|
||||
|
||||
fun contains(number : Int) : Boolean {
|
||||
if (reversed) {
|
||||
return (number <= start) && (number > start - size);
|
||||
} else {
|
||||
return (number >= start) && (number < start + size);
|
||||
}
|
||||
}
|
||||
|
||||
fun iterator() = RangeIterator(start, size, reversed);
|
||||
}
|
||||
|
||||
|
||||
|
||||
fun box() = testRange() && testReversedRange();
|
||||
|
||||
fun testRange() : Boolean {
|
||||
|
||||
val oneToFive = NumberRange(1, 4, false);
|
||||
if (oneToFive.contains(5)) return false;
|
||||
if (oneToFive.contains(0)) return false;
|
||||
if (oneToFive.contains(-100)) return false;
|
||||
if (oneToFive.contains(10)) return false;
|
||||
if (!oneToFive.contains(1)) return false;
|
||||
if (!oneToFive.contains(2)) return false;
|
||||
if (!oneToFive.contains(3)) return false;
|
||||
if (!oneToFive.contains(4)) return false;
|
||||
if (!(oneToFive.start == 1)) return false;
|
||||
if (!(oneToFive.size == 4)) return false;
|
||||
if (!(oneToFive.end == 5)) return false;
|
||||
|
||||
var sum = 0;
|
||||
for (i in oneToFive) {
|
||||
sum += i;
|
||||
}
|
||||
for (i in oneToFive) {
|
||||
System.out?.print(i)
|
||||
}
|
||||
|
||||
if (sum != 10) return false;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
fun testReversedRange() : Boolean {
|
||||
|
||||
System.out?.println("Testing revesed range.");
|
||||
|
||||
val tenToFive = NumberRange(10, 5, true);
|
||||
|
||||
if (tenToFive.contains(5)) return false;
|
||||
if (tenToFive.contains(11)) return false;
|
||||
if (tenToFive.contains(-100)) return false;
|
||||
if (tenToFive.contains(1000)) return false;
|
||||
if (!tenToFive.contains(6)) return false;
|
||||
if (!tenToFive.contains(7)) return false;
|
||||
if (!tenToFive.contains(8)) return false;
|
||||
if (!tenToFive.contains(9)) return false;
|
||||
if (!tenToFive.contains(10)) return false;
|
||||
|
||||
for (i in tenToFive) {
|
||||
System.out?.println(i)
|
||||
}
|
||||
|
||||
|
||||
var sum = 0;
|
||||
for (i in tenToFive) {
|
||||
sum += i;
|
||||
}
|
||||
|
||||
if (sum != 40) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
fun main(args : Array<String>) {
|
||||
System.out?.println(box())
|
||||
}
|
||||
@@ -446,6 +446,12 @@ Object.extend(Function.prototype, (function () {
|
||||
})());
|
||||
|
||||
Kotlin = {}
|
||||
Kotlin.Class = Class;
|
||||
Kotlin.Namespace = Namespace;
|
||||
Kotlin.Trait = Trait;
|
||||
Kotlin.isType = isType;
|
||||
|
||||
|
||||
Kotlin.Exceptions = {}
|
||||
Kotlin.Exceptions.IndexOutOfBounds = {}
|
||||
Kotlin.array = function (len) {
|
||||
@@ -574,7 +580,60 @@ Kotlin.System = function () {
|
||||
};
|
||||
}();
|
||||
|
||||
Kotlin.Class = Class;
|
||||
Kotlin.Namespace = Namespace;
|
||||
Kotlin.Trait = Trait;
|
||||
Kotlin.isType = isType;
|
||||
|
||||
Kotlin.ArrayIterator = Class.create({
|
||||
initialize:function (array) {
|
||||
this.array = array;
|
||||
this.index = 0;
|
||||
},
|
||||
next:function () {
|
||||
return this.array.get(this.index++);
|
||||
},
|
||||
hasNext:function () {
|
||||
return (this.array.size() > this.index);
|
||||
}
|
||||
});
|
||||
|
||||
Kotlin.RangeIterator = Kotlin.Class.create({initialize:function (start, count, reversed) {
|
||||
this.$start = start;
|
||||
this.$count = count;
|
||||
this.$reversed = reversed;
|
||||
}, 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;
|
||||
}, next:function () {
|
||||
this.set_count(this.get_count() - 1);
|
||||
return this.get_start() + (this.get_reversed() ? -this.get_count() : this.get_count());
|
||||
}, hasNext:function () {
|
||||
return this.get_count() > 0;
|
||||
}
|
||||
});
|
||||
|
||||
Kotlin.NumberRange = Kotlin.Class.create({initialize:function (start, size, reversed) {
|
||||
this.$start = start;
|
||||
this.$size = size;
|
||||
this.$reversed = reversed;
|
||||
}, get_start:function () {
|
||||
return this.$start;
|
||||
}, get_size:function () {
|
||||
return this.$size;
|
||||
}, get_reversed:function () {
|
||||
return this.$reversed;
|
||||
}, get_end:function () {
|
||||
return this.get_start() + this.get_size();
|
||||
}, 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();
|
||||
}
|
||||
}, iterator:function () {
|
||||
return new Kotlin.RangeIterator(this.get_start(), this.get_size(), this.get_reversed());
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,31 @@
|
||||
namespace foo
|
||||
|
||||
fun box() : Boolean {
|
||||
|
||||
var oneToFive = IntRange(1, 4)
|
||||
|
||||
if (oneToFive.contains(5)) return false;
|
||||
if (oneToFive.contains(0)) return false;
|
||||
if (oneToFive.contains(-100)) return false;
|
||||
if (oneToFive.contains(10)) return false;
|
||||
if (!oneToFive.contains(1)) return false;
|
||||
if (!oneToFive.contains(2)) return false;
|
||||
if (!oneToFive.contains(3)) return false;
|
||||
if (!oneToFive.contains(4)) return false;
|
||||
if (!(oneToFive.start == 1)) return false;
|
||||
if (!(oneToFive.size == 4)) return false;
|
||||
if (!(oneToFive.end == 5)) return false;
|
||||
|
||||
var sum = 0;
|
||||
for (i in oneToFive) {
|
||||
sum += i;
|
||||
}
|
||||
for (i in oneToFive) {
|
||||
System.out?.print(i)
|
||||
}
|
||||
|
||||
if (sum != 10) return false;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user