store nullability information in TypeInfo
This commit is contained in:
@@ -49,10 +49,11 @@ public class ClassCodegen {
|
||||
}
|
||||
|
||||
|
||||
public static void newTypeInfo(InstructionAdapter v, Type asmType) {
|
||||
public static void newTypeInfo(InstructionAdapter v, boolean isNullable, Type asmType) {
|
||||
v.anew(JetTypeMapper.TYPE_TYPEINFO);
|
||||
v.dup();
|
||||
v.aconst(asmType);
|
||||
v.invokespecial("jet/typeinfo/TypeInfo", "<init>", "(Ljava/lang/Class;)V");
|
||||
v.aconst(isNullable);
|
||||
v.invokespecial("jet/typeinfo/TypeInfo", "<init>", "(Ljava/lang/Class;Z)V");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1453,7 +1453,7 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
for (JetTypeProjection jetTypeArgument : expression.getTypeArguments()) {
|
||||
JetType typeArgument = bindingContext.resolveTypeReference(jetTypeArgument.getTypeReference());
|
||||
// TODO is the makeNullable() call correct here?
|
||||
ClassCodegen.newTypeInfo(v, typeMapper.mapType(TypeUtils.makeNullable(typeArgument)));
|
||||
ClassCodegen.newTypeInfo(v, typeArgument.isNullable(), typeMapper.mapType(TypeUtils.makeNullable(typeArgument)));
|
||||
}
|
||||
|
||||
v.invokespecial(JetTypeMapper.jvmNameForImplementation(classDecl), "<init>", method.getDescriptor());
|
||||
@@ -1724,6 +1724,7 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
v.anew(JetTypeMapper.TYPE_TYPEINFO);
|
||||
v.dup();
|
||||
v.aconst(jvmType);
|
||||
v.aconst(jetType.isNullable());
|
||||
List<TypeProjection> arguments = jetType.getArguments();
|
||||
if (arguments.size() > 0) {
|
||||
v.iconst(arguments.size());
|
||||
@@ -1736,10 +1737,10 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
generateTypeInfo(argument.getType());
|
||||
v.astore(JetTypeMapper.TYPE_OBJECT);
|
||||
}
|
||||
v.invokespecial("jet/typeinfo/TypeInfo", "<init>", "(Ljava/lang/Class;[Ljet/typeinfo/TypeInfo;)V");
|
||||
v.invokespecial("jet/typeinfo/TypeInfo", "<init>", "(Ljava/lang/Class;Z[Ljet/typeinfo/TypeInfo;)V");
|
||||
}
|
||||
else {
|
||||
v.invokespecial("jet/typeinfo/TypeInfo", "<init>", "(Ljava/lang/Class;)V");
|
||||
v.invokespecial("jet/typeinfo/TypeInfo", "<init>", "(Ljava/lang/Class;Z)V");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -318,6 +318,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
iv.dup();
|
||||
|
||||
iv.aconst(state.getTypeMapper().jvmType(descriptor, OwnerKind.INTERFACE));
|
||||
iv.aconst(false);
|
||||
iv.iconst(typeParamCount);
|
||||
iv.newarray(JetTypeMapper.TYPE_TYPEINFO);
|
||||
|
||||
@@ -327,7 +328,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
iv.load(firstTypeParameter + i, JetTypeMapper.TYPE_OBJECT);
|
||||
iv.astore(JetTypeMapper.TYPE_OBJECT);
|
||||
}
|
||||
iv.invokespecial("jet/typeinfo/TypeInfo", "<init>", "(Ljava/lang/Class;[Ljet/typeinfo/TypeInfo;)V");
|
||||
iv.invokespecial("jet/typeinfo/TypeInfo", "<init>", "(Ljava/lang/Class;Z[Ljet/typeinfo/TypeInfo;)V");
|
||||
iv.putfield(state.getTypeMapper().jvmName(descriptor, OwnerKind.IMPLEMENTATION), "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||
}
|
||||
|
||||
@@ -394,7 +395,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
if (needTypeInfo) {
|
||||
JetTypeMapper typeMapper = state.getTypeMapper();
|
||||
ClassCodegen.newTypeInfo(v, typeMapper.jvmType(descriptor, OwnerKind.INTERFACE));
|
||||
ClassCodegen.newTypeInfo(v, false, typeMapper.jvmType(descriptor, OwnerKind.INTERFACE));
|
||||
v.putstatic(typeMapper.jvmName(descriptor, kind), "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||
}
|
||||
if (needInstance) {
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
class Box<T>(t: T) {
|
||||
var value = t
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val nullableBox = Box<String?>("")
|
||||
val notnullBox = Box<String>("")
|
||||
if (nullableBox is Box<String>) return "fail 1"
|
||||
if (notnullBox is Box<String?>) return "fail 2"
|
||||
if (nullableBox !is Box<String?>) return "fail 3"
|
||||
if (notnullBox !is Box<String>) return "fail 4"
|
||||
return "OK"
|
||||
}
|
||||
@@ -88,6 +88,10 @@ public class TypeInfoTest extends CodegenTestCase {
|
||||
blackBoxFile("typeInfo/primitiveTypeInfo.jet");
|
||||
}
|
||||
|
||||
public void testNullability() throws Exception {
|
||||
blackBoxFile("typeInfo/nullability.jet");
|
||||
}
|
||||
|
||||
private Runnable newRunnable() {
|
||||
return new Runnable() {
|
||||
@Override
|
||||
|
||||
@@ -10,15 +10,18 @@ import java.util.Arrays;
|
||||
public class TypeInfo<T> implements JetObject {
|
||||
private TypeInfo<?> typeInfo;
|
||||
private final Class<T> theClass;
|
||||
private final boolean nullable;
|
||||
private final TypeInfo[] typeParameters;
|
||||
|
||||
public TypeInfo(Class<T> theClass) {
|
||||
public TypeInfo(Class<T> theClass, boolean nullable) {
|
||||
this.theClass = theClass;
|
||||
this.nullable = nullable;
|
||||
this.typeParameters = null;
|
||||
}
|
||||
|
||||
public TypeInfo(Class<T> theClass, TypeInfo[] typeParameters) {
|
||||
public TypeInfo(Class<T> theClass, boolean nullable, TypeInfo[] typeParameters) {
|
||||
this.theClass = theClass;
|
||||
this.nullable = nullable;
|
||||
this.typeParameters = typeParameters;
|
||||
}
|
||||
|
||||
@@ -33,6 +36,9 @@ public class TypeInfo<T> implements JetObject {
|
||||
if (!theClass.isAssignableFrom(other.theClass)) {
|
||||
return false;
|
||||
}
|
||||
if (nullable != other.nullable) {
|
||||
return false;
|
||||
}
|
||||
if (typeParameters != null) {
|
||||
if (other.typeParameters == null || other.typeParameters.length != typeParameters.length) {
|
||||
throw new IllegalArgumentException("inconsistent type infos for the same class");
|
||||
@@ -68,6 +74,7 @@ public class TypeInfo<T> implements JetObject {
|
||||
TypeInfo typeInfo = (TypeInfo) o;
|
||||
|
||||
if (!theClass.equals(typeInfo.theClass)) return false;
|
||||
if (nullable != typeInfo.nullable) return false;
|
||||
if (!Arrays.equals(typeParameters, typeInfo.typeParameters)) return false;
|
||||
|
||||
return true;
|
||||
@@ -80,12 +87,12 @@ public class TypeInfo<T> implements JetObject {
|
||||
return result;
|
||||
}
|
||||
|
||||
public static final TypeInfo<Byte> BYTE_TYPE_INFO = new TypeInfo<Byte>(Byte.class);
|
||||
public static final TypeInfo<Short> SHORT_TYPE_INFO = new TypeInfo<Short>(Short.class);
|
||||
public static final TypeInfo<Integer> INT_TYPE_INFO = new TypeInfo<Integer>(Integer.class);
|
||||
public static final TypeInfo<Long> LONG_TYPE_INFO = new TypeInfo<Long>(Long.class);
|
||||
public static final TypeInfo<Character> CHAR_TYPE_INFO = new TypeInfo<Character>(Character.class);
|
||||
public static final TypeInfo<Boolean> BOOL_TYPE_INFO = new TypeInfo<Boolean>(Boolean.class);
|
||||
public static final TypeInfo<Float> FLOAT_TYPE_INFO = new TypeInfo<Float>(Float.class);
|
||||
public static final TypeInfo<Double> DOUBLE_TYPE_INFO = new TypeInfo<Double>(Double.class);
|
||||
public static final TypeInfo<Byte> BYTE_TYPE_INFO = new TypeInfo<Byte>(Byte.class, false);
|
||||
public static final TypeInfo<Short> SHORT_TYPE_INFO = new TypeInfo<Short>(Short.class, false);
|
||||
public static final TypeInfo<Integer> INT_TYPE_INFO = new TypeInfo<Integer>(Integer.class, false);
|
||||
public static final TypeInfo<Long> LONG_TYPE_INFO = new TypeInfo<Long>(Long.class, false);
|
||||
public static final TypeInfo<Character> CHAR_TYPE_INFO = new TypeInfo<Character>(Character.class, false);
|
||||
public static final TypeInfo<Boolean> BOOL_TYPE_INFO = new TypeInfo<Boolean>(Boolean.class, false);
|
||||
public static final TypeInfo<Float> FLOAT_TYPE_INFO = new TypeInfo<Float>(Float.class, false);
|
||||
public static final TypeInfo<Double> DOUBLE_TYPE_INFO = new TypeInfo<Double>(Double.class, false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user