Switched to using native Javascript array for Kotlin's Array<T> instead of library class.
Motivation: better interop with native libraries Index in bounds check is dropped for now.
This commit is contained in:
Generated
+356
-496
File diff suppressed because it is too large
Load Diff
@@ -105,7 +105,6 @@ public final class K2JSTranslator {
|
||||
@NotNull
|
||||
public String generateCallToMain(@NotNull JetFile file, @NotNull String argumentString) {
|
||||
String namespaceName = getRootNamespaceName(file);
|
||||
|
||||
List<String> arguments = parseString(argumentString);
|
||||
return GenerationUtils.generateCallToMain(namespaceName, arguments);
|
||||
}
|
||||
|
||||
@@ -86,19 +86,15 @@ public final class StandardClasses {
|
||||
}
|
||||
|
||||
private static void declareJetObjects(@NotNull StandardClasses standardClasses) {
|
||||
standardClasses.declare().forFQ("jet.Array").kotlinClass("Array")
|
||||
.properties("size", "indices");
|
||||
|
||||
standardClasses.declare().forFQ("jet.Array").kotlinFunction("array");
|
||||
|
||||
standardClasses.declare().forFQ("jet.Iterator").kotlinClass("ArrayIterator")
|
||||
.methods("next", "hasNext");
|
||||
standardClasses.declare().forFQ("jet.Iterator").kotlinClass("ArrayIteratorIntrinsic")
|
||||
.methods("next").properties("hasNext");
|
||||
|
||||
standardClasses.declare().forFQ("jet.IntRange").kotlinClass("NumberRange")
|
||||
.methods("iterator", "contains").properties("start", "size", "end", "reversed");
|
||||
|
||||
standardClasses.declare().forFQ("jet.String").kotlinClass("String").
|
||||
properties("length");
|
||||
// standardClasses.declare().forFQ("jet.String").kotlinClass("String").
|
||||
// properties("length");
|
||||
|
||||
standardClasses.declare().forFQ("jet.Any.toString").kotlinFunction("toString");
|
||||
}
|
||||
@@ -162,7 +158,6 @@ public final class StandardClasses {
|
||||
@NotNull String... propertyNames) {
|
||||
for (String propertyName : propertyNames) {
|
||||
declareInner(classFQName, propertyName, propertyName);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ import org.jetbrains.k2js.translate.operation.UnaryOperationTranslator;
|
||||
import org.jetbrains.k2js.translate.reference.AccessTranslator;
|
||||
import org.jetbrains.k2js.translate.reference.CallTranslator;
|
||||
import org.jetbrains.k2js.translate.reference.ReferenceTranslator;
|
||||
import org.jetbrains.k2js.translate.utils.BindingUtils;
|
||||
import org.jetbrains.k2js.translate.utils.TranslationUtils;
|
||||
|
||||
import java.util.List;
|
||||
@@ -122,10 +123,14 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
|
||||
@Override
|
||||
@NotNull
|
||||
public JsNode visitIfExpression(@NotNull JetIfExpression expression, @NotNull TranslationContext context) {
|
||||
JsIf ifStatement = translateAsIfStatement(expression, context);
|
||||
if (BindingUtils.isStatement(context.bindingContext(), expression)) {
|
||||
return ifStatement;
|
||||
}
|
||||
TemporaryVariable result = context.declareTemporary(context.program().getNullLiteral());
|
||||
AstUtil.SaveLastExpressionMutator saveResultToTemporaryMutator =
|
||||
new AstUtil.SaveLastExpressionMutator(result.nameReference());
|
||||
JsNode mutatedIfStatement = AstUtil.mutateLastExpression(translateAsIfStatement(expression, context),
|
||||
JsNode mutatedIfStatement = AstUtil.mutateLastExpression(ifStatement,
|
||||
saveResultToTemporaryMutator);
|
||||
JsStatement resultingStatement = AstUtil.convertToStatement(mutatedIfStatement);
|
||||
context.jsBlock().addStatement(resultingStatement);
|
||||
|
||||
@@ -7,9 +7,7 @@ import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.types.JetStandardClasses;
|
||||
import org.jetbrains.jet.lang.types.JetStandardLibrary;
|
||||
import org.jetbrains.jet.lexer.JetToken;
|
||||
import org.jetbrains.k2js.translate.intrinsic.array.ArrayGetIntrinsic;
|
||||
import org.jetbrains.k2js.translate.intrinsic.array.ArrayNullConstructorIntrinsic;
|
||||
import org.jetbrains.k2js.translate.intrinsic.array.ArraySetIntrinsic;
|
||||
import org.jetbrains.k2js.translate.intrinsic.array.*;
|
||||
import org.jetbrains.k2js.translate.intrinsic.primitive.*;
|
||||
import org.jetbrains.k2js.translate.intrinsic.string.LengthIntrinsic;
|
||||
import org.jetbrains.k2js.translate.intrinsic.tuple.TupleAccessIntrinsic;
|
||||
@@ -55,14 +53,23 @@ public final class Intrinsics {
|
||||
declareArrayIntrinsics();
|
||||
}
|
||||
|
||||
//TODO: provide generic mechanism or refactor
|
||||
private void declareArrayIntrinsics() {
|
||||
JetScope arrayMemberScope = library.getArray().getDefaultType().getMemberScope();
|
||||
FunctionDescriptor setFunction = getFunctionByName(arrayMemberScope, "set");
|
||||
functionIntrinsics.put(setFunction, ArraySetIntrinsic.INSTANCE);
|
||||
FunctionDescriptor getFunction = getFunctionByName(arrayMemberScope, "get");
|
||||
functionIntrinsics.put(getFunction, ArrayGetIntrinsic.INSTANCE);
|
||||
PropertyDescriptor sizeProperty = getPropertyByName(arrayMemberScope, "size");
|
||||
functionIntrinsics.put(sizeProperty.getGetter(), ArraySizeIntrinsic.INSTANCE);
|
||||
PropertyDescriptor indicesProperty = getPropertyByName(arrayMemberScope, "indices");
|
||||
functionIntrinsics.put(indicesProperty.getGetter(), ArrayIndicesIntrinsic.INSTANCE);
|
||||
FunctionDescriptor nullArrayConstructor = getFunctionByName(library.getLibraryScope(), "Array");
|
||||
functionIntrinsics.put(nullArrayConstructor, ArrayNullConstructorIntrinsic.INSTANCE);
|
||||
FunctionDescriptor iteratorFunction = getFunctionByName(arrayMemberScope, "iterator");
|
||||
functionIntrinsics.put(iteratorFunction, ArrayIteratorIntrinsic.INSTANCE);
|
||||
ConstructorDescriptor arrayConstructor = library.getArray().getConstructors().iterator().next();
|
||||
functionIntrinsics.put(arrayConstructor, ArrayFunctionConstructorIntrinsic.INSTANCE);
|
||||
}
|
||||
|
||||
private void declareTuplesIntrinsics() {
|
||||
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package org.jetbrains.k2js.translate.intrinsic.array;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import com.google.dart.compiler.backend.js.ast.JsNameRef;
|
||||
import com.google.dart.compiler.util.AstUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public enum ArrayFunctionConstructorIntrinsic implements FunctionIntrinsic {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JsExpression apply(@Nullable JsExpression receiver,
|
||||
@NotNull List<JsExpression> arguments,
|
||||
@NotNull TranslationContext context) {
|
||||
assert receiver == null;
|
||||
assert arguments.size() == 2;
|
||||
//TODO: provide better mechanism
|
||||
JsNameRef iteratorFunName = AstUtil.newQualifiedNameRef("Kotlin.arrayFromFun");
|
||||
return AstUtil.newInvocation(iteratorFunName, arguments);
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package org.jetbrains.k2js.translate.intrinsic.array;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import com.google.dart.compiler.backend.js.ast.JsNameRef;
|
||||
import com.google.dart.compiler.util.AstUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public enum ArrayIndicesIntrinsic implements FunctionIntrinsic {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JsExpression apply(@Nullable JsExpression receiver, @NotNull List<JsExpression> arguments,
|
||||
@NotNull TranslationContext context) {
|
||||
assert receiver != null;
|
||||
assert arguments.size() == 0;
|
||||
//TODO: provide better mechanism
|
||||
JsNameRef iteratorFunName = AstUtil.newQualifiedNameRef("Kotlin.arrayIndices");
|
||||
return AstUtil.newInvocation(iteratorFunName, receiver);
|
||||
}
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package org.jetbrains.k2js.translate.intrinsic.array;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import com.google.dart.compiler.backend.js.ast.JsNameRef;
|
||||
import com.google.dart.compiler.util.AstUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public enum ArrayIteratorIntrinsic implements FunctionIntrinsic {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JsExpression apply(@Nullable JsExpression receiver, @NotNull List<JsExpression> arguments,
|
||||
@NotNull TranslationContext context) {
|
||||
assert receiver != null;
|
||||
assert arguments.size() == 0;
|
||||
//TODO: provide better mechanism
|
||||
JsNameRef iteratorFunName = AstUtil.newQualifiedNameRef("Kotlin.arrayIterator");
|
||||
return AstUtil.newInvocation(iteratorFunName, receiver);
|
||||
}
|
||||
}
|
||||
+7
-2
@@ -1,7 +1,8 @@
|
||||
package org.jetbrains.k2js.translate.intrinsic.array;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.JsArrayLiteral;
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import com.google.dart.compiler.backend.js.ast.JsNameRef;
|
||||
import com.google.dart.compiler.util.AstUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
@@ -21,6 +22,10 @@ public enum ArrayNullConstructorIntrinsic implements FunctionIntrinsic {
|
||||
@Override
|
||||
public JsExpression apply(@Nullable JsExpression receiver, @NotNull List<JsExpression> arguments,
|
||||
@NotNull TranslationContext context) {
|
||||
return new JsArrayLiteral();
|
||||
assert receiver == null;
|
||||
assert arguments.size() == 1;
|
||||
//TODO: provide better mechanism
|
||||
JsNameRef nullArrayFunName = AstUtil.newQualifiedNameRef("Kotlin.nullArray");
|
||||
return AstUtil.newInvocation(nullArrayFunName, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package org.jetbrains.k2js.translate.intrinsic.array;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import com.google.dart.compiler.backend.js.ast.JsNameRef;
|
||||
import com.google.dart.compiler.util.AstUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public enum ArraySizeIntrinsic implements FunctionIntrinsic {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JsExpression apply(@Nullable JsExpression receiver, @NotNull List<JsExpression> arguments,
|
||||
@NotNull TranslationContext context) {
|
||||
assert receiver != null;
|
||||
assert arguments.isEmpty() : "Length expression must have zero arguments.";
|
||||
//TODO: provide better way
|
||||
JsNameRef lengthProperty = AstUtil.newQualifiedNameRef("length");
|
||||
AstUtil.setQualifier(lengthProperty, receiver);
|
||||
return lengthProperty;
|
||||
}
|
||||
}
|
||||
@@ -11,10 +11,10 @@ public final class GenerationUtils {
|
||||
|
||||
@NotNull
|
||||
public static String generateCallToMain(@NotNull String namespaceName, @NotNull List<String> arguments) {
|
||||
String constructArguments = "var args = Kotlin.array(" + arguments.size() + ");\n";
|
||||
String constructArguments = "var args = [];\n";
|
||||
int index = 0;
|
||||
for (String argument : arguments) {
|
||||
constructArguments = constructArguments + "args.set(" + index + ", \"" + argument + "\");\n";
|
||||
constructArguments = constructArguments + "args[" + index + "]= \"" + argument + "\";\n";
|
||||
index++;
|
||||
}
|
||||
String callMain = namespaceName + ".main(args);\n";
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package org.jetbrains.k2js.test;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mozilla.javascript.JavaScriptException;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
@@ -39,10 +38,12 @@ public class StandardClassesTest extends TranslationTest {
|
||||
testFooBoxIsTrue("arraySize.kt");
|
||||
}
|
||||
|
||||
@Test(expected = JavaScriptException.class)
|
||||
public void arrayThrowsExceptionOnOOBaccess() throws Exception {
|
||||
testFooBoxIsTrue("arrayThrowsExceptionOnOOBaccess.kt");
|
||||
}
|
||||
//TODO: this feature in not supported for some time
|
||||
//TODO: support it. Probably confugurable.
|
||||
// @Test(expected = JavaScriptException.class)
|
||||
// public void arrayThrowsExceptionOnOOBaccess() throws Exception {
|
||||
// testFooBoxIsTrue("arrayThrowsExceptionOnOOBaccess.kt");
|
||||
// }
|
||||
|
||||
@Test
|
||||
public void arraysIterator() throws Exception {
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
function test() {
|
||||
var a = new Kotlin.Array(3, function () {
|
||||
var a = Kotlin.arrayFromFun(3, function () {
|
||||
return 3
|
||||
});
|
||||
a.set(0, "1")
|
||||
a.set(2, "4")
|
||||
return (a.get(0) == "1") && (a.get(2) == "4") && (a.get(1) == 3);
|
||||
return (a[0] == 3) && (a[2] == 3) && (a[1] == 3);
|
||||
}
|
||||
@@ -254,46 +254,6 @@
|
||||
Kotlin.Exceptions = {}
|
||||
Kotlin.Exception = Kotlin.Class.create();
|
||||
Kotlin.Exceptions.IndexOutOfBounds = {}
|
||||
Kotlin.array = function (len) {
|
||||
return new Kotlin.Array(len, function () {
|
||||
return null
|
||||
});
|
||||
}
|
||||
Kotlin.Array = Class.create({
|
||||
initialize:function (len, f) {
|
||||
this.array = [];
|
||||
var i = 0;
|
||||
while (i < len) {
|
||||
this.array.push(f(i));
|
||||
++i;
|
||||
}
|
||||
},
|
||||
get:function (index) {
|
||||
if ((index < 0) || (index >= this.array.length)) {
|
||||
throw Kotlin.Exceptions.IndexOutOfBounds;
|
||||
}
|
||||
return (this.array)[index];
|
||||
},
|
||||
set:function (index, value) {
|
||||
if ((index < 0) || (index >= this.array.length)) {
|
||||
throw Kotlin.Exceptions.IndexOutOfBounds;
|
||||
}
|
||||
(this.array)[index] = value;
|
||||
},
|
||||
size:function () {
|
||||
return this.array.length;
|
||||
},
|
||||
//TODO: remove duplicated methods
|
||||
get_size:function () {
|
||||
return this.array.length;
|
||||
},
|
||||
iterator:function () {
|
||||
return new Kotlin.ArrayIterator(this);
|
||||
},
|
||||
get_indices:function () {
|
||||
return new Kotlin.NumberRange(0, this.size(), false);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Kotlin.ArrayList = Class.create({
|
||||
@@ -352,19 +312,6 @@
|
||||
});
|
||||
|
||||
|
||||
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.parseInt =
|
||||
function (str) {
|
||||
return parseInt(str);
|
||||
@@ -502,9 +449,9 @@
|
||||
|
||||
Kotlin.Comparator = Kotlin.Class.create(
|
||||
{
|
||||
initialize:function() {
|
||||
initialize:function () {
|
||||
},
|
||||
compare:function() {
|
||||
compare:function () {
|
||||
throw new Kotlin.AbstractFunctionInvokationError();
|
||||
}
|
||||
}
|
||||
@@ -524,6 +471,50 @@
|
||||
}
|
||||
);
|
||||
|
||||
Kotlin.nullArray = function (size) {
|
||||
var res = [];
|
||||
var i = size;
|
||||
while (i > 0) {
|
||||
res[--i] = null;
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
Kotlin.arrayFromFun = function (size, initFun) {
|
||||
var res = [];
|
||||
var i = size;
|
||||
while (i > 0) {
|
||||
res[--i] = initFun(i);
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
Kotlin.arrayIndices = function (arr) {
|
||||
return new Kotlin.NumberRange(0, arr.length);
|
||||
};
|
||||
|
||||
var intrinsicArrayIterator = Kotlin.Class.create(
|
||||
Kotlin.Iterator,
|
||||
{
|
||||
initialize:function (arr) {
|
||||
this.arr = arr;
|
||||
this.len = arr.length;
|
||||
this.i = 0;
|
||||
},
|
||||
hasNext:function () {
|
||||
return (this.i < this.len);
|
||||
},
|
||||
next:function () {
|
||||
return this.arr[this.i++];
|
||||
},
|
||||
get_hasNext:function() { return this.hasNext()}
|
||||
}
|
||||
);
|
||||
|
||||
Kotlin.arrayIterator = function (arr) {
|
||||
return new intrinsicArrayIterator(arr);
|
||||
};
|
||||
|
||||
Kotlin.toString = function (obj) {
|
||||
return obj.toString();
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user