[] for collections

This commit is contained in:
Dmitry Jemerov
2011-07-06 12:31:18 +02:00
parent 7b47d67dca
commit d71bcf5df4
3 changed files with 66 additions and 3 deletions
@@ -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));
}
}
@@ -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;
@@ -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<String>) { l[0] = \"Jet\" + l[0]; }");
final Method main = generateFunction();
final ArrayList<String> list = new ArrayList<String>();
list.add("Language");
main.invoke(null, list);
assertEquals("JetLanguage", list.get(0));
}
}