tuple support and tests
This commit is contained in:
@@ -38,9 +38,22 @@ public final class StandardClasses {
|
||||
declareJavaCollection(standardClasses);
|
||||
declareMap(standardClasses);
|
||||
declareInteger(standardClasses);
|
||||
// declareTuples(standardClasses);
|
||||
return standardClasses;
|
||||
}
|
||||
|
||||
// private static void declareTuples(@NotNull StandardClasses standardClasses) {
|
||||
// for (int tupleId = 0; tupleId <= JetStandardClasses.TUPLE_COUNT) {
|
||||
// declareTuple(standardClasses, tupleId);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private static void declareTuple(@NotNull StandardClasses standardClasses,
|
||||
// int tupleId) {
|
||||
// String tupleFQName = "jet.Tuple" + tupleId;
|
||||
//
|
||||
// }
|
||||
|
||||
private static void declareMap(@NotNull StandardClasses standardClasses) {
|
||||
String hashMapFQName = "java.util.Map";
|
||||
standardClasses.declareStandardTopLevelObject(hashMapFQName, "Map");
|
||||
|
||||
@@ -343,4 +343,15 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
|
||||
@NotNull TranslationContext context) {
|
||||
return TryTranslator.translate(expression, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public JsNode visitTupleExpression(@NotNull JetTupleExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
JsArrayLiteral result = new JsArrayLiteral();
|
||||
for (JetExpression entry : expression.getEntries()) {
|
||||
result.getExpressions().add(Translation.translateAsExpression(entry, context));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -3,13 +3,13 @@ package org.jetbrains.k2js.translate.intrinsic;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
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.primitive.*;
|
||||
import org.jetbrains.k2js.translate.intrinsic.string.LengthIntrinsic;
|
||||
import org.jetbrains.k2js.translate.intrinsic.tuple.TupleAccessIntrinsic;
|
||||
import org.jetbrains.k2js.translate.operation.OperatorTable;
|
||||
import org.jetbrains.k2js.translate.utils.DescriptorUtils;
|
||||
|
||||
@@ -17,7 +17,6 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.jetbrains.jet.lang.types.expressions.OperatorConventions.*;
|
||||
import static org.jetbrains.k2js.translate.utils.DescriptorUtils.getFunctionByName;
|
||||
import static org.jetbrains.k2js.translate.utils.DescriptorUtils.getPropertyByName;
|
||||
|
||||
/**
|
||||
@@ -48,8 +47,21 @@ public final class Intrinsics {
|
||||
this.library = library;
|
||||
declareOperatorIntrinsics();
|
||||
declareStringIntrinsics();
|
||||
//TODO: array intrinsic are under consideration
|
||||
//declareArrayIntrinsics();
|
||||
declareTuplesIntrinsics();
|
||||
}
|
||||
|
||||
private void declareTuplesIntrinsics() {
|
||||
for (int tupleSize = 0; tupleSize < JetStandardClasses.TUPLE_COUNT; ++tupleSize) {
|
||||
declareTupleIntrinsics(tupleSize);
|
||||
}
|
||||
}
|
||||
|
||||
private void declareTupleIntrinsics(int tupleSize) {
|
||||
JetScope libraryScope = library.getLibraryScope();
|
||||
assert libraryScope != null;
|
||||
ClassifierDescriptor tupleDescriptor = libraryScope.getClassifier("Tuple" + tupleSize);
|
||||
assert tupleDescriptor != null;
|
||||
declareTupleIntrinsicAccessors(tupleDescriptor, tupleSize);
|
||||
}
|
||||
|
||||
private void declareStringIntrinsics() {
|
||||
@@ -58,6 +70,16 @@ public final class Intrinsics {
|
||||
functionIntrinsics.put(lengthProperty.getGetter(), LengthIntrinsic.INSTANCE);
|
||||
}
|
||||
|
||||
private void declareTupleIntrinsicAccessors(@NotNull ClassifierDescriptor tupleDescriptor,
|
||||
int tupleSize) {
|
||||
for (int elementIndex = 0; elementIndex < tupleSize; ++elementIndex) {
|
||||
String accessorName = "_" + (elementIndex + 1);
|
||||
PropertyDescriptor propertyDescriptor =
|
||||
getPropertyByName(tupleDescriptor.getDefaultType().getMemberScope(), accessorName);
|
||||
functionIntrinsics.put(propertyDescriptor.getGetter(), new TupleAccessIntrinsic(elementIndex));
|
||||
}
|
||||
}
|
||||
|
||||
private void declareOperatorIntrinsics() {
|
||||
IntrinsicDeclarationVisitor visitor = new IntrinsicDeclarationVisitor();
|
||||
for (DeclarationDescriptor descriptor : library.getLibraryScope().getAllDescriptors()) {
|
||||
@@ -66,19 +88,6 @@ public final class Intrinsics {
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: delete or include
|
||||
private void declareArrayIntrinsics() {
|
||||
FunctionDescriptor constructorFunction = getFunctionByName(library.getLibraryScope(), "Array");
|
||||
functionIntrinsics.put(constructorFunction, ArrayNullConstructorIntrinsic.INSTANCE);
|
||||
|
||||
FunctionDescriptor getFunction = getFunctionByName(library.getArray(), "get");
|
||||
functionIntrinsics.put(getFunction, ArrayGetIntrinsic.INSTANCE);
|
||||
|
||||
FunctionDescriptor setFunction = getFunctionByName(library.getArray(), "set");
|
||||
functionIntrinsics.put(setFunction, ArraySetIntrinsic.INSTANCE);
|
||||
|
||||
}
|
||||
|
||||
public boolean isIntrinsic(@NotNull DeclarationDescriptor descriptor) {
|
||||
//NOTE: that if we want to add other intrinsics we have to modify this method
|
||||
if (descriptor instanceof FunctionDescriptor) {
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package org.jetbrains.k2js.translate.intrinsic.tuple;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import com.google.dart.compiler.util.AstUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public final class TupleAccessIntrinsic implements FunctionIntrinsic {
|
||||
|
||||
private final int elementIndex;
|
||||
|
||||
public TupleAccessIntrinsic(int elementIndex) {
|
||||
this.elementIndex = elementIndex;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JsExpression apply(@NotNull JsExpression receiver, @NotNull List<JsExpression> arguments,
|
||||
@NotNull TranslationContext context) {
|
||||
assert arguments.isEmpty() : "Tuple access expression should not have any arguments.";
|
||||
return AstUtil.newArrayAccess(receiver, context.program().getNumberLiteral(elementIndex));
|
||||
}
|
||||
}
|
||||
@@ -91,7 +91,7 @@ public final class DescriptorUtils {
|
||||
variable = scope.getPropertyByFieldReference("$" + name);
|
||||
}
|
||||
Set<VariableDescriptor> variables = scope.getProperties(name);
|
||||
assert variables.size() == 1;
|
||||
assert variables.size() == 1 : "Actual size: " + variables.size();
|
||||
variable = variables.iterator().next();
|
||||
PropertyDescriptor descriptor = (PropertyDescriptor) variable;
|
||||
assert descriptor != null : "Must have a descriptor.";
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package org.jetbrains.k2js.test;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public class TupleTest extends TranslationTest {
|
||||
public final class TupleTest extends TranslationTest {
|
||||
|
||||
final private static String MAIN = "tuple/";
|
||||
|
||||
@@ -12,11 +14,16 @@ public class TupleTest extends TranslationTest {
|
||||
return MAIN;
|
||||
}
|
||||
|
||||
//TODO: excluded because Tuples are not implemented
|
||||
// @Test
|
||||
// public void twoElements() throws Exception {
|
||||
// testFooBoxIsTrue("twoElements.kt");
|
||||
// }
|
||||
@Test
|
||||
public void twoElements() throws Exception {
|
||||
testFooBoxIsTrue("twoElements.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleMembers() throws Exception {
|
||||
testFooBoxIsTrue("multipleMembers.kt");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package foo
|
||||
|
||||
fun box() : Boolean {
|
||||
if (#(1, 2, 3)._1 != 1) return false;
|
||||
if (#("a", "b")._2 != "b") return false;
|
||||
val x = #("1", 2, "3", 4, "5", 6);
|
||||
if (x._1 != "1") return false;
|
||||
if (x._2 != 2) return false;
|
||||
if (x._2 != 2) return false;
|
||||
if (x._6 != 6) return false;
|
||||
if (x._5 != "5") return false;
|
||||
if (x._3 != "3") return false;
|
||||
if (#(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)._21 != 1) return false;
|
||||
return true;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package foo
|
||||
|
||||
fun box() : Boolean {
|
||||
val a : (Int, Int) = (1, 2)
|
||||
return (a._1 == 1)
|
||||
val a : #(Int, Int) = #(1, 2)
|
||||
return ((a._1 == 1) && (a._2 == 2))
|
||||
}
|
||||
Reference in New Issue
Block a user