From d71bcf5df44eabbd102bc7c4a960c5425f603a1a Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 6 Jul 2011 12:31:18 +0200 Subject: [PATCH] [] for collections --- .../jet/codegen/ExpressionCodegen.java | 19 +++++++-- .../org/jetbrains/jet/codegen/StackValue.java | 41 +++++++++++++++++++ .../jet/codegen/NamespaceGenTest.java | 9 ++++ 3 files changed, 66 insertions(+), 3 deletions(-) diff --git a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 044372e3e82..6f6ef95c26d 100644 --- a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -1472,14 +1472,27 @@ public class ExpressionCodegen extends JetVisitor { public void visitArrayAccessExpression(JetArrayAccessExpression expression) { final JetExpression array = expression.getArrayExpression(); final Type arrayType = expressionType(array); + gen(array, arrayType); + generateArrayIndex(expression); if (arrayType.getSort() == Type.ARRAY) { - gen(array, arrayType); - generateArrayIndex(expression); final Type elementType = arrayType.getElementType(); myStack.push(StackValue.arrayElement(elementType)); } else { - throw new UnsupportedOperationException("array access to non-Java arrays is not supported"); + final PsiElement declaration = bindingContext.resolveToDeclarationPsiElement(expression); + final CallableMethod accessor; + if (declaration instanceof PsiMethod) { + accessor = JetTypeMapper.mapToCallableMethod((PsiMethod) declaration); + } + else if (declaration instanceof JetNamedFunction) { + accessor = typeMapper.mapToCallableMethod((JetNamedFunction) declaration); + } + else { + throw new UnsupportedOperationException("unknown accessor type"); + } + boolean isGetter = accessor.getSignature().getName().equals("get"); + myStack.push(StackValue.collectionElement(JetTypeMapper.TYPE_OBJECT, isGetter ? accessor : null, + isGetter ? null : accessor)); } } diff --git a/idea/src/org/jetbrains/jet/codegen/StackValue.java b/idea/src/org/jetbrains/jet/codegen/StackValue.java index cbeb23af8b4..3a5d8c2b202 100644 --- a/idea/src/org/jetbrains/jet/codegen/StackValue.java +++ b/idea/src/org/jetbrains/jet/codegen/StackValue.java @@ -67,6 +67,10 @@ public abstract class StackValue { return new ArrayElement(type); } + public static StackValue collectionElement(Type type, CallableMethod getter, CallableMethod setter) { + return new CollectionElement(type, getter, setter); + } + public static StackValue field(Type type, String owner, String name, boolean isStatic) { return new Field(type, owner, name, isStatic); } @@ -383,6 +387,43 @@ public abstract class StackValue { } } + private static class CollectionElement extends StackValue { + private final CallableMethod getter; + private final CallableMethod setter; + + public CollectionElement(Type type, CallableMethod getter, CallableMethod setter) { + super(type); + this.getter = getter; + this.setter = setter; + } + + @Override + public void put(Type type, InstructionAdapter v) { + if (getter == null) { + throw new UnsupportedOperationException("no getter specified"); + } + getter.invoke(v); + } + + @Override + public void store(InstructionAdapter v) { + if (setter == null) { + throw new UnsupportedOperationException("no setter specified"); + } + setter.invoke(v); + } + + @Override + public void dupReceiver(InstructionAdapter v, int below) { + if (below == 1) { + v.dup2X1(); + } + else { + v.dup2(); // collection and index + } + } + } + private static class Field extends StackValue { private final String owner; diff --git a/idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java b/idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java index 676730f06e9..8f34886b537 100644 --- a/idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java +++ b/idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java @@ -426,4 +426,13 @@ public class NamespaceGenTest extends CodegenTestCase { main.invoke(null, list); assertEquals("foo", list.get(0)); } + + public void testArrayAccessForArrayList() throws Exception { + loadText("import java.util.*; fun foo(l: ArrayList) { l[0] = \"Jet\" + l[0]; }"); + final Method main = generateFunction(); + final ArrayList list = new ArrayList(); + list.add("Language"); + main.invoke(null, list); + assertEquals("JetLanguage", list.get(0)); + } }