supported array access expressions.

This commit is contained in:
Pavel Talanov
2011-11-30 19:59:42 +04:00
parent 6edcd6e9a1
commit b77133bd59
7 changed files with 144 additions and 5 deletions
@@ -13,6 +13,7 @@ import org.jetbrains.k2js.translate.general.TranslationContext;
import org.jetbrains.k2js.translate.general.TranslatorVisitor;
import org.jetbrains.k2js.translate.operation.BinaryOperationTranslator;
import org.jetbrains.k2js.translate.operation.UnaryOperationTranslator;
import org.jetbrains.k2js.translate.reference.ArrayAccessTranslator;
import org.jetbrains.k2js.translate.reference.PropertyAccessTranslator;
import org.jetbrains.k2js.translate.reference.ReferenceTranslator;
import org.jetbrains.k2js.translate.utils.BindingUtils;
@@ -189,9 +190,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
private JsExpression translateConditionExpression(@Nullable JetExpression expression,
@NotNull TranslationContext context) {
JsExpression jsCondition = translateNullableExpression(expression, context);
if (jsCondition == null) {
throw new AssertionError("Empty condition!");
}
assert (jsCondition != null) : "Condition should not be empty";
return AstUtil.convertToExpression(jsCondition);
}
@@ -385,5 +384,12 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
return new JsThisRef();
}
@Override
@NotNull
public JsInvocation visitArrayAccessExpression(@NotNull JetArrayAccessExpression expression,
@NotNull TranslationContext context) {
return ArrayAccessTranslator.translateAsArrayGetterCall(expression, context);
}
}
@@ -10,6 +10,7 @@ import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
import org.jetbrains.jet.lexer.JetToken;
import org.jetbrains.k2js.translate.general.Translation;
import org.jetbrains.k2js.translate.general.TranslationContext;
import org.jetbrains.k2js.translate.reference.ArrayAccessTranslator;
import org.jetbrains.k2js.translate.reference.PropertyAccessTranslator;
/**
@@ -48,6 +49,9 @@ public final class BinaryOperationTranslator extends OperationTranslator {
@NotNull
JsExpression translate() {
if (ArrayAccessTranslator.canBeArraySetterCall(expression)) {
return ArrayAccessTranslator.translateAsArraySetterCall(expression, context());
}
if (isCompareTo()) {
return asCompareToOverload();
}
@@ -0,0 +1,106 @@
package org.jetbrains.k2js.translate.reference;
import com.google.dart.compiler.backend.js.ast.JsExpression;
import com.google.dart.compiler.backend.js.ast.JsInvocation;
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.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.psi.JetArrayAccessExpression;
import org.jetbrains.jet.lang.psi.JetBinaryExpression;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lexer.JetToken;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.general.Translation;
import org.jetbrains.k2js.translate.general.TranslationContext;
import org.jetbrains.k2js.translate.operation.OperatorTable;
import org.jetbrains.k2js.translate.utils.BindingUtils;
import org.jetbrains.k2js.translate.utils.TranslationUtils;
import java.util.List;
/**
* @author Talanov Pavel
*/
public final class ArrayAccessTranslator extends AbstractTranslator {
public static boolean canBeArraySetterCall(@NotNull JetBinaryExpression expression) {
//TODO: move unsafe cat to util
return (OperatorTable.isAssignment((JetToken) expression.getOperationToken())
&& (expression.getLeft() instanceof JetArrayAccessExpression));
}
public static JsInvocation translateAsArrayGetterCall(@NotNull JetArrayAccessExpression expression,
@NotNull TranslationContext context) {
return (new ArrayAccessTranslator(expression, null, context)).translateAsArrayGet();
}
public static JsInvocation translateAsArraySetterCall(@NotNull JetBinaryExpression expression,
@NotNull TranslationContext context) {
JetExpression arrayAccess = expression.getLeft();
assert (arrayAccess instanceof JetArrayAccessExpression) : "Check with canBeArraySetterCall";
JetExpression right = expression.getRight();
assert right != null : "Binary expression should have a right expression";
JsExpression expressionToSetTo = Translation.translateAsExpression(right, context);
return (new ArrayAccessTranslator((JetArrayAccessExpression) arrayAccess, expressionToSetTo, context))
.translateAsArraySet();
}
@NotNull
private final JetArrayAccessExpression expression;
@NotNull
private final DeclarationDescriptor methodDescriptor;
@Nullable
private final JsExpression expressionToSetTo;
private ArrayAccessTranslator(@NotNull JetArrayAccessExpression expression,
@Nullable JsExpression expressionToSetTo,
@NotNull TranslationContext context) {
super(context);
this.expression = expression;
DeclarationDescriptor descriptorForReferenceExpression =
BindingUtils.getDescriptorForReferenceExpression(context.bindingContext(), expression);
assert descriptorForReferenceExpression != null : "Array access expression must reference a descriptor";
this.methodDescriptor = descriptorForReferenceExpression;
this.expressionToSetTo = expressionToSetTo;
}
@NotNull
private JsInvocation translateAsArrayGet() {
return translateAsArrayAccessWithIndices();
}
private JsInvocation translateAsArrayAccessWithIndices() {
JsNameRef accessMethodReference = getAccessMethodReference();
AstUtil.setQualifier(accessMethodReference, translateArrayExpression());
return AstUtil.newInvocation(accessMethodReference, translateIndexExpressions());
}
@NotNull
private JsInvocation translateAsArraySet() {
assert expressionToSetTo != null;
JsInvocation setCall = translateAsArrayAccessWithIndices();
setCall.getArguments().add(expressionToSetTo);
return setCall;
}
@NotNull
private List<JsExpression> translateIndexExpressions() {
return TranslationUtils.translateExpressionList(context(), expression.getIndexExpressions());
}
@NotNull
private JsNameRef getAccessMethodReference() {
return context().getNameForDescriptor(methodDescriptor).makeRef();
}
@NotNull
private JsExpression translateArrayExpression() {
return Translation.translateAsExpression(expression.getArrayExpression(), context());
}
}
@@ -167,4 +167,14 @@ public final class TranslationUtils {
}
return qualifier;
}
@NotNull
public static List<JsExpression> translateExpressionList(@NotNull TranslationContext context,
@NotNull List<JetExpression> expressions) {
List<JsExpression> result = new ArrayList<JsExpression>();
for (JetExpression expression : expressions) {
result.add(Translation.translateAsExpression(expression, context));
}
return result;
}
}
@@ -17,4 +17,9 @@ public class StandardClassesTest extends TranslationTest {
public void array() throws Exception {
testFooBoxIsTrue("array.kt");
}
@Test
public void arrayAccess() throws Exception {
testFooBoxIsTrue("arrayAccess.kt");
}
}
+2 -2
View File
@@ -452,10 +452,10 @@ Kotlin.Array = Class.create({
this.array = [];
},
get:function (index) {
return this.array[index];
return (this.array)[index];
},
set:function (index, value) {
this.array[index] = value;
(this.array)[index] = value;
}
})
@@ -0,0 +1,8 @@
namespace foo
fun box() : Boolean {
val a = Array<Int>(4)
a[1] = 2
a[2] = 3
return a.get(1) == 2
}