initial implementation of as?
This commit is contained in:
@@ -73,7 +73,7 @@ public class ClassCodegen {
|
||||
ClassVisitor v = kind == OwnerKind.IMPLEMENTATION ? factory.forClassImplementation(descriptor) : factory.forClassDelegatingImplementation(descriptor);
|
||||
v.visit(Opcodes.V1_6,
|
||||
Opcodes.ACC_PUBLIC,
|
||||
JetTypeMapper.jvmName(descriptor, kind),
|
||||
JetTypeMapper.jetJvmName(descriptor, kind),
|
||||
null,
|
||||
superClass,
|
||||
new String[] { "jet/JetObject", JetTypeMapper.jvmNameForInterface(descriptor) }
|
||||
@@ -113,7 +113,7 @@ public class ClassCodegen {
|
||||
else if (first instanceof JetDelegatorToSuperCall) {
|
||||
JetType superType = bindingContext.resolveTypeReference(first.getTypeReference());
|
||||
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
||||
return JetTypeMapper.jvmName(superClassDescriptor, kind);
|
||||
return typeMapper.jvmName(superClassDescriptor, kind);
|
||||
}
|
||||
|
||||
return "java/lang/Object";
|
||||
@@ -177,7 +177,7 @@ public class ClassCodegen {
|
||||
final InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
ExpressionCodegen codegen = new ExpressionCodegen(mv, bindingContext, frameMap, typeMapper, Type.VOID_TYPE, classDescriptor, kind);
|
||||
|
||||
String classname = JetTypeMapper.jvmName(classDescriptor, kind);
|
||||
String classname = typeMapper.jvmName(classDescriptor, kind);
|
||||
final Type classType = Type.getType("L" + classname + ";");
|
||||
|
||||
if (kind == OwnerKind.DELEGATING_IMPLEMENTATION) {
|
||||
|
||||
@@ -43,6 +43,7 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
private static final String ITERATOR_NEXT_DESCRIPTOR = "()Ljava/lang/Object;";
|
||||
private static final String INT_RANGE_CONSTRUCTOR_DESCRIPTOR = "(II)V";
|
||||
|
||||
private static final Type OBJECT_TYPE = Type.getType(Object.class);
|
||||
private static final Type ITERATOR_TYPE = Type.getType(Iterator.class);
|
||||
private static final Type INT_RANGE_TYPE = Type.getType(IntRange.class);
|
||||
private static final Type JET_OBJECT_TYPE = Type.getType(JetObject.class);
|
||||
@@ -501,11 +502,11 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
String fieldOwner;
|
||||
String interfaceOwner;
|
||||
if (isInsideClass || isStatic) {
|
||||
fieldOwner = interfaceOwner = JetTypeMapper.getOwner(propertyDescriptor, contextKind);
|
||||
fieldOwner = interfaceOwner = typeMapper.getOwner(propertyDescriptor, contextKind);
|
||||
}
|
||||
else {
|
||||
fieldOwner = null;
|
||||
interfaceOwner = JetTypeMapper.getOwner(propertyDescriptor, OwnerKind.INTERFACE);
|
||||
interfaceOwner = typeMapper.getOwner(propertyDescriptor, OwnerKind.INTERFACE);
|
||||
}
|
||||
|
||||
return StackValue.property(propertyDescriptor.getName(), fieldOwner, interfaceOwner, typeMapper.mapType(outType), isStatic, getter, setter);
|
||||
@@ -1201,7 +1202,7 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
v.load(0, JetTypeMapper.jetImplementationType(contextClass));
|
||||
}
|
||||
else if (contextKind == OwnerKind.DELEGATING_IMPLEMENTATION) {
|
||||
v.getfield(JetTypeMapper.jvmName(contextClass, contextKind), "$this", JetTypeMapper.jetInterfaceType(contextClass).getDescriptor());
|
||||
v.getfield(typeMapper.jvmName(contextClass, contextKind), "$this", JetTypeMapper.jetInterfaceType(contextClass).getDescriptor());
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException("Unknown kind: " + contextKind);
|
||||
@@ -1242,11 +1243,35 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
@Override
|
||||
public void visitBinaryWithTypeRHSExpression(JetBinaryExpressionWithTypeRHS expression) {
|
||||
JetSimpleNameExpression operationSign = expression.getOperationSign();
|
||||
if (operationSign.getReferencedNameElementType() == JetTokens.COLON) {
|
||||
IElementType opToken = operationSign.getReferencedNameElementType();
|
||||
if (opToken == JetTokens.COLON) {
|
||||
gen(expression.getLeft());
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException("should generate a cast, but don't know how");
|
||||
JetTypeReference typeReference = expression.getRight();
|
||||
JetType jetType = bindingContext.resolveTypeReference(typeReference);
|
||||
if (jetType.getArguments().size() > 0) {
|
||||
throw new UnsupportedOperationException("don't know how to handle type arguments in as/as?");
|
||||
}
|
||||
DeclarationDescriptor descriptor = jetType.getConstructor().getDeclarationDescriptor();
|
||||
if (!(descriptor instanceof ClassDescriptor)) {
|
||||
throw new UnsupportedOperationException("don't know how to handle non-class types in as/as?");
|
||||
}
|
||||
Type type = typeMapper.jvmType((ClassDescriptor) descriptor, OwnerKind.INTERFACE);
|
||||
gen(expression.getLeft(), OBJECT_TYPE);
|
||||
if (opToken == JetTokens.AS_SAFE) {
|
||||
v.dup();
|
||||
v.instanceOf(type);
|
||||
Label isInstance = new Label();
|
||||
v.ifne(isInstance);
|
||||
v.pop();
|
||||
v.aconst(null);
|
||||
v.mark(isInstance);
|
||||
myStack.push(StackValue.onStack(type));
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException("as not yet implemented");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,15 @@ public class JetTypeMapper {
|
||||
return psiClass.getQualifiedName().replace(".", "/");
|
||||
}
|
||||
|
||||
static String jvmName(ClassDescriptor jetClass, OwnerKind kind) {
|
||||
public String jvmName(ClassDescriptor jetClass, OwnerKind kind) {
|
||||
PsiElement declaration = bindingContext.getDeclarationPsiElement(jetClass);
|
||||
if (declaration instanceof PsiClass) {
|
||||
return jvmName((PsiClass) declaration);
|
||||
}
|
||||
return jetJvmName(jetClass, kind);
|
||||
}
|
||||
|
||||
public static String jetJvmName(ClassDescriptor jetClass, OwnerKind kind) {
|
||||
if (kind == OwnerKind.INTERFACE) {
|
||||
return jvmNameForInterface(jetClass);
|
||||
}
|
||||
@@ -48,6 +56,10 @@ public class JetTypeMapper {
|
||||
}
|
||||
}
|
||||
|
||||
public Type jvmType(ClassDescriptor jetClass, OwnerKind kind) {
|
||||
return Type.getType("L" + jvmName(jetClass, kind) + ";");
|
||||
}
|
||||
|
||||
static Type psiClassType(PsiClass psiClass) {
|
||||
return Type.getType("L" + jvmName(psiClass) + ";");
|
||||
}
|
||||
@@ -84,7 +96,7 @@ public class JetTypeMapper {
|
||||
return jvmNameForInterface(descriptor) + "$$DImpl";
|
||||
}
|
||||
|
||||
static String getOwner(DeclarationDescriptor descriptor, OwnerKind kind) {
|
||||
public String getOwner(DeclarationDescriptor descriptor, OwnerKind kind) {
|
||||
String owner;
|
||||
if (descriptor.getContainingDeclaration() instanceof NamespaceDescriptor) {
|
||||
owner = jvmName((NamespaceDescriptor) descriptor.getContainingDeclaration());
|
||||
|
||||
@@ -160,7 +160,7 @@ public class PropertyCodegen {
|
||||
}
|
||||
else {
|
||||
iv.visitFieldInsn(kind == OwnerKind.NAMESPACE ? Opcodes.GETSTATIC : Opcodes.GETFIELD,
|
||||
JetTypeMapper.getOwner(propertyDescriptor, kind), propertyDescriptor.getName(),
|
||||
mapper.getOwner(propertyDescriptor, kind), propertyDescriptor.getName(),
|
||||
type.getDescriptor());
|
||||
}
|
||||
iv.areturn(type);
|
||||
@@ -206,7 +206,7 @@ public class PropertyCodegen {
|
||||
else {
|
||||
iv.load(paramCode, type);
|
||||
iv.visitFieldInsn(kind == OwnerKind.NAMESPACE ? Opcodes.PUTSTATIC : Opcodes.PUTFIELD,
|
||||
JetTypeMapper.getOwner(propertyDescriptor, kind), propertyDescriptor.getName(),
|
||||
mapper.getOwner(propertyDescriptor, kind), propertyDescriptor.getName(),
|
||||
type.getDescriptor());
|
||||
}
|
||||
|
||||
|
||||
@@ -28,5 +28,18 @@ public class TypeInfoTest extends CodegenTestCase {
|
||||
TypeInfo typeInfo = (TypeInfo) foo.invoke(null);
|
||||
assertNotNull(typeInfo);
|
||||
}
|
||||
|
||||
public void testAsSafeOperator() throws Exception {
|
||||
loadText("fun foo(x: Any) = x as? Runnable");
|
||||
System.out.println(generateToText());
|
||||
Method foo = generateFunction();
|
||||
assertNull(foo.invoke(null, new Object()));
|
||||
Runnable r = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
}
|
||||
};
|
||||
assertSame(r, foo.invoke(null, r));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user