array codegen bugs
This commit is contained in:
@@ -1,13 +1,12 @@
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassKind;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetClass;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.TypeProjection;
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
@@ -54,4 +53,8 @@ public class CodegenUtil {
|
||||
}
|
||||
return (ClassDescriptor) outerDescriptor;
|
||||
}
|
||||
|
||||
public static Type arrayElementType(Type type) {
|
||||
return Type.getType(type.getDescriptor().substring(1));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -378,8 +378,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
|
||||
gen(expression.getLoopRange(), loopRangeType); // array
|
||||
v.load(myIndexVar, Type.INT_TYPE);
|
||||
v.aload(loopRangeType.getElementType());
|
||||
StackValue.onStack(loopRangeType.getElementType()).put(asmParamType, v);
|
||||
v.aload(CodegenUtil.arrayElementType(loopRangeType));
|
||||
StackValue.onStack(CodegenUtil.arrayElementType(loopRangeType)).put(asmParamType, v);
|
||||
v.store(lookupLocal(parameterDescriptor), asmParamType);
|
||||
}
|
||||
|
||||
@@ -1683,12 +1683,23 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
}
|
||||
|
||||
private void generateNewArray(JetCallExpression expression, Type type) {
|
||||
JetType arrayType = bindingContext.get(BindingContext.EXPRESSION_TYPE, expression);
|
||||
|
||||
List<? extends ValueArgument> args = expression.getValueArguments();
|
||||
if (args.size() != 1) {
|
||||
throw new CompilationException("array constructor requires one value argument");
|
||||
}
|
||||
gen(args.get(0).getArgumentExpression(), Type.INT_TYPE);
|
||||
v.newarray(type.getElementType());
|
||||
|
||||
JetType elementType = typeMapper.getGenericsElementType(arrayType);
|
||||
if(elementType != null) {
|
||||
generateTypeInfo(elementType);
|
||||
v.invokestatic("jet/typeinfo/TypeInfo", "newArray", "(ILjet/typeinfo/TypeInfo;)[Ljava/lang/Object;");
|
||||
v.checkcast(type);
|
||||
}
|
||||
else {
|
||||
v.newarray(CodegenUtil.arrayElementType(type));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1698,7 +1709,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
gen(array, arrayType);
|
||||
generateArrayIndex(expression);
|
||||
if (arrayType.getSort() == Type.ARRAY) {
|
||||
final Type elementType = arrayType.getElementType();
|
||||
final Type elementType = CodegenUtil.arrayElementType(arrayType);
|
||||
return StackValue.arrayElement(elementType);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -670,4 +670,20 @@ public class JetTypeMapper {
|
||||
public String isKnownTypeInfo(JetType jetType) {
|
||||
return knowTypes.get(jetType);
|
||||
}
|
||||
|
||||
public boolean isGenericsArray(JetType type) {
|
||||
DeclarationDescriptor declarationDescriptor = type.getConstructor().getDeclarationDescriptor();
|
||||
if(declarationDescriptor instanceof TypeParameterDescriptor)
|
||||
return true;
|
||||
|
||||
if(standardLibrary.getArray().equals(declarationDescriptor))
|
||||
return isGenericsArray(type.getArguments().get(0).getType());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public JetType getGenericsElementType(JetType arrayType) {
|
||||
JetType type = arrayType.getArguments().get(0).getType();
|
||||
return isGenericsArray(type) ? type : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,7 +152,7 @@ public class NamespaceCodegen {
|
||||
v.aconst(jvmType);
|
||||
v.iconst(jetType.isNullable() ? 1 : 0);
|
||||
List<TypeProjection> arguments = jetType.getArguments();
|
||||
if (arguments.size() > 0) {
|
||||
if (arguments.size() > 0 && !(jvmType.getSort() == Type.ARRAY && jvmType.getElementType().getSort() != Type.OBJECT)) {
|
||||
v.iconst(arguments.size());
|
||||
v.newarray(JetTypeMapper.TYPE_TYPEINFOPROJECTION);
|
||||
|
||||
|
||||
@@ -186,7 +186,7 @@ public abstract class StackValue {
|
||||
else
|
||||
v.iconst(0);
|
||||
}
|
||||
else if (type.getSort() == Type.OBJECT && this.type.equals(JetTypeMapper.TYPE_OBJECT)) {
|
||||
else if (type.getSort() == Type.OBJECT && this.type.equals(JetTypeMapper.TYPE_OBJECT) || type.getSort() == Type.ARRAY) {
|
||||
v.checkcast(type);
|
||||
}
|
||||
else if (type.getSort() == Type.OBJECT) {
|
||||
@@ -431,6 +431,7 @@ public abstract class StackValue {
|
||||
@Override
|
||||
public void put(Type type, InstructionAdapter v) {
|
||||
v.aload(type); // assumes array and index are on the stack
|
||||
coerce(type, v);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
namespace test
|
||||
|
||||
class List<T>() {
|
||||
val a : Array<T> = Array<T>(1)
|
||||
}
|
||||
|
||||
fun box() : String {
|
||||
val a = List<String>()
|
||||
a.a[0] = "1"
|
||||
println(a.a[0])
|
||||
|
||||
val b = List<Int?>()
|
||||
b.a[0] = 10
|
||||
println(b.a[0])
|
||||
|
||||
val c = List<Array<Int>>()
|
||||
c.a[0] = Array<Int>(4)
|
||||
println(c.a[0].size)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
fun println(s : Any?) {
|
||||
System.out?.println(s);
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class ArrayGenTest extends CodegenTestCase {
|
||||
public void testKt238 () throws Exception {
|
||||
blackBoxFile("regressions/kt238.jet");
|
||||
}
|
||||
|
||||
public void testKt326 () throws Exception {
|
||||
blackBoxFile("regressions/kt326.jet");
|
||||
}
|
||||
|
||||
public void testCreateMultiInt () throws Exception {
|
||||
loadText("fun foo() = Array<Array<Int>> (5)");
|
||||
Method foo = generateFunction();
|
||||
Object invoke = foo.invoke(null);
|
||||
System.out.println(invoke.getClass());
|
||||
assertTrue(invoke instanceof int[][]);
|
||||
}
|
||||
|
||||
public void testCreateMultiString () throws Exception {
|
||||
loadText("fun foo() = Array<Array<String>> (5)");
|
||||
Method foo = generateFunction();
|
||||
Object invoke = foo.invoke(null);
|
||||
System.out.println(invoke.getClass());
|
||||
assertTrue(invoke instanceof String[][]);
|
||||
}
|
||||
|
||||
public void testCreateMultiGenerics () throws Exception {
|
||||
/*
|
||||
loadText("class L<T>() { val a = Array<T>(5) } fun foo() = L<Int>.a");
|
||||
System.out.println(generateToText());
|
||||
Method foo = generateFunction();
|
||||
Object invoke = foo.invoke(null);
|
||||
System.out.println(invoke.getClass());
|
||||
assertTrue(invoke instanceof Integer[]);
|
||||
*/
|
||||
}
|
||||
|
||||
public void testIntGenerics () throws Exception {
|
||||
loadText("class L<T>(var a : T) {} fun foo() = L<Int>(5).a");
|
||||
System.out.println(generateToText());
|
||||
Method foo = generateFunction();
|
||||
Object invoke = foo.invoke(null);
|
||||
System.out.println(invoke.getClass());
|
||||
assertTrue(invoke instanceof Integer);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
public class ArrayGenTestCase extends CodegenTestCase {
|
||||
public void testKt238 () throws Exception {
|
||||
blackBoxFile("regressions/kt238.jet");
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package jet.typeinfo;
|
||||
import jet.JetObject;
|
||||
import jet.Tuple0;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.TypeVariable;
|
||||
import java.util.*;
|
||||
@@ -37,6 +38,10 @@ public abstract class TypeInfo<T> implements JetObject {
|
||||
public static final TypeInfo<Double> NULLABLE_DOUBLE_TYPE_INFO = getTypeInfo(Double.class, true);
|
||||
public static final TypeInfo<String> NULLABLE_STRING_TYPE_INFO = getTypeInfo(String.class, true);
|
||||
public static final TypeInfo<Tuple0> NULLABLE_TUPLE0_TYPE_INFO = getTypeInfo(Tuple0.class, true);
|
||||
|
||||
public static Object [] newArray(int length, TypeInfo typeInfo) {
|
||||
return (Object[]) Array.newInstance(((TypeInfoImpl) typeInfo).signature.klazz, length);
|
||||
}
|
||||
|
||||
public static <T> TypeInfoProjection invariantProjection(final TypeInfo<T> typeInfo) {
|
||||
return (TypeInfoProjection) typeInfo;
|
||||
|
||||
Reference in New Issue
Block a user