tuple support and tests

This commit is contained in:
Pavel Talanov
2012-01-24 19:54:38 +04:00
parent 3826f15b7c
commit 46b7ab194a
8 changed files with 112 additions and 28 deletions
@@ -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))
}