[] for collections
This commit is contained in:
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user