'is' works for type parameters
This commit is contained in:
@@ -425,14 +425,7 @@ public class ClassCodegen {
|
||||
null);
|
||||
mv.visitCode();
|
||||
InstructionAdapter v = new InstructionAdapter(mv);
|
||||
String owner = JetTypeMapper.jvmNameForImplementation(descriptor);
|
||||
if (descriptor.getTypeConstructor().getParameters().size() > 0) {
|
||||
v.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||
v.getfield(owner, "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||
}
|
||||
else {
|
||||
v.getstatic(owner, "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||
}
|
||||
ExpressionCodegen.loadTypeInfo(descriptor, v);
|
||||
v.areturn(JetTypeMapper.TYPE_TYPEINFO);
|
||||
mv.visitMaxs(0, 0);
|
||||
mv.visitEnd();
|
||||
|
||||
@@ -76,6 +76,17 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
this.bindingContext = bindingContext;
|
||||
}
|
||||
|
||||
static void loadTypeInfo(ClassDescriptor descriptor, InstructionAdapter v) {
|
||||
String owner = JetTypeMapper.jvmNameForImplementation(descriptor);
|
||||
if (descriptor.getTypeConstructor().getParameters().size() > 0) {
|
||||
v.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||
v.getfield(owner, "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||
}
|
||||
else {
|
||||
v.getstatic(owner, "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||
}
|
||||
}
|
||||
|
||||
private void gen(JetElement expr) {
|
||||
if (expr == null) throw new CompilationException();
|
||||
expr.accept(this);
|
||||
@@ -1301,7 +1312,7 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
throw new UnsupportedOperationException("don't know how to handle non-class types in is");
|
||||
}
|
||||
if (jetType.getArguments().size() > 0) {
|
||||
newTypeInfo(jetType);
|
||||
generateTypeInfo(jetType);
|
||||
gen(expression.getLeftHandSide(), OBJECT_TYPE);
|
||||
v.invokevirtual("jet/typeinfo/TypeInfo", "isInstance", "(Ljava/lang/Object;)Z");
|
||||
}
|
||||
@@ -1314,11 +1325,23 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
myStack.push(expression.isNot() ? StackValue.not(value) : value);
|
||||
}
|
||||
|
||||
private void newTypeInfo(JetType jetType) {
|
||||
private void generateTypeInfo(JetType jetType) {
|
||||
DeclarationDescriptor declarationDescriptor = jetType.getConstructor().getDeclarationDescriptor();
|
||||
if (declarationDescriptor instanceof TypeParameterDescriptor) {
|
||||
DeclarationDescriptor containingDeclaration = declarationDescriptor.getContainingDeclaration();
|
||||
if (containingDeclaration == contextType && contextType instanceof ClassDescriptor) {
|
||||
int index = indexOfTypeParameter((ClassDescriptor) contextType, (TypeParameterDescriptor) declarationDescriptor);
|
||||
loadTypeInfo((ClassDescriptor) contextType, v);
|
||||
v.iconst(index);
|
||||
v.invokevirtual("jet/typeinfo/TypeInfo", "getTypeParameter", "(I)Ljet/typeinfo/TypeInfo;");
|
||||
return;
|
||||
}
|
||||
throw new UnsupportedOperationException("don't know what this type parameter resolves to");
|
||||
}
|
||||
|
||||
v.anew(JetTypeMapper.TYPE_TYPEINFO);
|
||||
v.dup();
|
||||
|
||||
v.aconst(typeMapper.jvmType((ClassDescriptor) jetType.getConstructor().getDeclarationDescriptor(), OwnerKind.INTERFACE));
|
||||
v.aconst(typeMapper.jvmType((ClassDescriptor) declarationDescriptor, OwnerKind.INTERFACE));
|
||||
List<TypeProjection> arguments = jetType.getArguments();
|
||||
if (arguments.size() > 0) {
|
||||
v.iconst(arguments.size());
|
||||
@@ -1328,7 +1351,7 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
TypeProjection argument = arguments.get(i);
|
||||
v.dup();
|
||||
v.iconst(i);
|
||||
newTypeInfo(argument.getType());
|
||||
generateTypeInfo(argument.getType());
|
||||
v.astore(JetTypeMapper.TYPE_OBJECT);
|
||||
}
|
||||
v.invokespecial("jet/typeinfo/TypeInfo", "<init>", "(Ljava/lang/Class;[Ljet/typeinfo/TypeInfo;)V");
|
||||
@@ -1338,6 +1361,15 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
private int indexOfTypeParameter(ClassDescriptor classDescriptor, TypeParameterDescriptor typeParameterDescriptor) {
|
||||
List<TypeParameterDescriptor> parameters = classDescriptor.getTypeConstructor().getParameters();
|
||||
int index = parameters.indexOf(typeParameterDescriptor);
|
||||
if (index < 0) {
|
||||
throw new UnsupportedOperationException("can't find type parameter index");
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
private static class CompilationException extends RuntimeException {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
class Wrapper<T>() {
|
||||
fun isSameWrapper(wrapper: Any) = wrapper is Wrapper<T>
|
||||
}
|
||||
|
||||
fun foo() {
|
||||
val wrapper = new Wrapper<Int>()
|
||||
return wrapper.isSameWrapper(new Wrapper<String>())
|
||||
}
|
||||
@@ -59,6 +59,12 @@ public class TypeInfoTest extends CodegenTestCase {
|
||||
assertFalse((Boolean) foo.invoke(null, newRunnable()));
|
||||
}
|
||||
|
||||
public void testIsWithGenericParameters() throws Exception {
|
||||
loadFile();
|
||||
Method foo = generateFunction();
|
||||
assertFalse((Boolean) foo.invoke(null));
|
||||
}
|
||||
|
||||
private Runnable newRunnable() {
|
||||
return new Runnable() {
|
||||
@Override
|
||||
|
||||
@@ -47,6 +47,10 @@ public class TypeInfo<T> implements JetObject {
|
||||
return true;
|
||||
}
|
||||
|
||||
public TypeInfo getTypeParameter(int index) {
|
||||
return typeParameters[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeInfo<?> getTypeInfo() {
|
||||
if (typeInfo == null) {
|
||||
|
||||
Reference in New Issue
Block a user