Merge branch 'master' of ssh://git.labs.intellij.net/jet
This commit is contained in:
@@ -1,13 +1,12 @@
|
|||||||
package org.jetbrains.jet.codegen;
|
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.ClassDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.ClassKind;
|
import org.jetbrains.jet.lang.descriptors.ClassKind;
|
||||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.JetClass;
|
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
|
import org.jetbrains.jet.lang.types.TypeProjection;
|
||||||
|
import org.objectweb.asm.Type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
@@ -54,4 +53,8 @@ public class CodegenUtil {
|
|||||||
}
|
}
|
||||||
return (ClassDescriptor) outerDescriptor;
|
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
|
gen(expression.getLoopRange(), loopRangeType); // array
|
||||||
v.load(myIndexVar, Type.INT_TYPE);
|
v.load(myIndexVar, Type.INT_TYPE);
|
||||||
v.aload(loopRangeType.getElementType());
|
v.aload(CodegenUtil.arrayElementType(loopRangeType));
|
||||||
StackValue.onStack(loopRangeType.getElementType()).put(asmParamType, v);
|
StackValue.onStack(CodegenUtil.arrayElementType(loopRangeType)).put(asmParamType, v);
|
||||||
v.store(lookupLocal(parameterDescriptor), asmParamType);
|
v.store(lookupLocal(parameterDescriptor), asmParamType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1683,12 +1683,23 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void generateNewArray(JetCallExpression expression, Type type) {
|
private void generateNewArray(JetCallExpression expression, Type type) {
|
||||||
|
JetType arrayType = bindingContext.get(BindingContext.EXPRESSION_TYPE, expression);
|
||||||
|
|
||||||
List<? extends ValueArgument> args = expression.getValueArguments();
|
List<? extends ValueArgument> args = expression.getValueArguments();
|
||||||
if (args.size() != 1) {
|
if (args.size() != 1) {
|
||||||
throw new CompilationException("array constructor requires one value argument");
|
throw new CompilationException("array constructor requires one value argument");
|
||||||
}
|
}
|
||||||
gen(args.get(0).getArgumentExpression(), Type.INT_TYPE);
|
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
|
@Override
|
||||||
@@ -1698,7 +1709,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
gen(array, arrayType);
|
gen(array, arrayType);
|
||||||
generateArrayIndex(expression);
|
generateArrayIndex(expression);
|
||||||
if (arrayType.getSort() == Type.ARRAY) {
|
if (arrayType.getSort() == Type.ARRAY) {
|
||||||
final Type elementType = arrayType.getElementType();
|
final Type elementType = CodegenUtil.arrayElementType(arrayType);
|
||||||
return StackValue.arrayElement(elementType);
|
return StackValue.arrayElement(elementType);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -670,4 +670,20 @@ public class JetTypeMapper {
|
|||||||
public String isKnownTypeInfo(JetType jetType) {
|
public String isKnownTypeInfo(JetType jetType) {
|
||||||
return knowTypes.get(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.aconst(jvmType);
|
||||||
v.iconst(jetType.isNullable() ? 1 : 0);
|
v.iconst(jetType.isNullable() ? 1 : 0);
|
||||||
List<TypeProjection> arguments = jetType.getArguments();
|
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.iconst(arguments.size());
|
||||||
v.newarray(JetTypeMapper.TYPE_TYPEINFOPROJECTION);
|
v.newarray(JetTypeMapper.TYPE_TYPEINFOPROJECTION);
|
||||||
|
|
||||||
|
|||||||
@@ -186,7 +186,7 @@ public abstract class StackValue {
|
|||||||
else
|
else
|
||||||
v.iconst(0);
|
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);
|
v.checkcast(type);
|
||||||
}
|
}
|
||||||
else if (type.getSort() == Type.OBJECT) {
|
else if (type.getSort() == Type.OBJECT) {
|
||||||
@@ -431,6 +431,7 @@ public abstract class StackValue {
|
|||||||
@Override
|
@Override
|
||||||
public void put(Type type, InstructionAdapter v) {
|
public void put(Type type, InstructionAdapter v) {
|
||||||
v.aload(type); // assumes array and index are on the stack
|
v.aload(type); // assumes array and index are on the stack
|
||||||
|
coerce(type, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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.JetObject;
|
||||||
import jet.Tuple0;
|
import jet.Tuple0;
|
||||||
|
|
||||||
|
import java.lang.reflect.Array;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.TypeVariable;
|
import java.lang.reflect.TypeVariable;
|
||||||
import java.util.*;
|
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<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<String> NULLABLE_STRING_TYPE_INFO = getTypeInfo(String.class, true);
|
||||||
public static final TypeInfo<Tuple0> NULLABLE_TUPLE0_TYPE_INFO = getTypeInfo(Tuple0.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) {
|
public static <T> TypeInfoProjection invariantProjection(final TypeInfo<T> typeInfo) {
|
||||||
return (TypeInfoProjection) typeInfo;
|
return (TypeInfoProjection) typeInfo;
|
||||||
|
|||||||
Reference in New Issue
Block a user