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.general.TranslatorVisitor;
import org.jetbrains.k2js.translate.operation.BinaryOperationTranslator; import org.jetbrains.k2js.translate.operation.BinaryOperationTranslator;
import org.jetbrains.k2js.translate.operation.UnaryOperationTranslator; 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.PropertyAccessTranslator;
import org.jetbrains.k2js.translate.reference.ReferenceTranslator; import org.jetbrains.k2js.translate.reference.ReferenceTranslator;
import org.jetbrains.k2js.translate.utils.BindingUtils; import org.jetbrains.k2js.translate.utils.BindingUtils;
@@ -189,9 +190,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
private JsExpression translateConditionExpression(@Nullable JetExpression expression, private JsExpression translateConditionExpression(@Nullable JetExpression expression,
@NotNull TranslationContext context) { @NotNull TranslationContext context) {
JsExpression jsCondition = translateNullableExpression(expression, context); JsExpression jsCondition = translateNullableExpression(expression, context);
if (jsCondition == null) { assert (jsCondition != null) : "Condition should not be empty";
throw new AssertionError("Empty condition!");
}
return AstUtil.convertToExpression(jsCondition); return AstUtil.convertToExpression(jsCondition);
} }
@@ -385,5 +384,12 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
return new JsThisRef(); 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.jet.lexer.JetToken;
import org.jetbrains.k2js.translate.general.Translation; import org.jetbrains.k2js.translate.general.Translation;
import org.jetbrains.k2js.translate.general.TranslationContext; import org.jetbrains.k2js.translate.general.TranslationContext;
import org.jetbrains.k2js.translate.reference.ArrayAccessTranslator;
import org.jetbrains.k2js.translate.reference.PropertyAccessTranslator; import org.jetbrains.k2js.translate.reference.PropertyAccessTranslator;
/** /**
@@ -48,6 +49,9 @@ public final class BinaryOperationTranslator extends OperationTranslator {
@NotNull @NotNull
JsExpression translate() { JsExpression translate() {
if (ArrayAccessTranslator.canBeArraySetterCall(expression)) {
return ArrayAccessTranslator.translateAsArraySetterCall(expression, context());
}
if (isCompareTo()) { if (isCompareTo()) {
return asCompareToOverload(); 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; 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 { public void array() throws Exception {
testFooBoxIsTrue("array.kt"); 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 = []; this.array = [];
}, },
get:function (index) { get:function (index) {
return this.array[index]; return (this.array)[index];
}, },
set:function (index, value) { 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
}