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);
|
ClassVisitor v = kind == OwnerKind.IMPLEMENTATION ? factory.forClassImplementation(descriptor) : factory.forClassDelegatingImplementation(descriptor);
|
||||||
v.visit(Opcodes.V1_6,
|
v.visit(Opcodes.V1_6,
|
||||||
Opcodes.ACC_PUBLIC,
|
Opcodes.ACC_PUBLIC,
|
||||||
JetTypeMapper.jvmName(descriptor, kind),
|
JetTypeMapper.jetJvmName(descriptor, kind),
|
||||||
null,
|
null,
|
||||||
superClass,
|
superClass,
|
||||||
new String[] { "jet/JetObject", JetTypeMapper.jvmNameForInterface(descriptor) }
|
new String[] { "jet/JetObject", JetTypeMapper.jvmNameForInterface(descriptor) }
|
||||||
@@ -113,7 +113,7 @@ public class ClassCodegen {
|
|||||||
else if (first instanceof JetDelegatorToSuperCall) {
|
else if (first instanceof JetDelegatorToSuperCall) {
|
||||||
JetType superType = bindingContext.resolveTypeReference(first.getTypeReference());
|
JetType superType = bindingContext.resolveTypeReference(first.getTypeReference());
|
||||||
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
||||||
return JetTypeMapper.jvmName(superClassDescriptor, kind);
|
return typeMapper.jvmName(superClassDescriptor, kind);
|
||||||
}
|
}
|
||||||
|
|
||||||
return "java/lang/Object";
|
return "java/lang/Object";
|
||||||
@@ -177,7 +177,7 @@ public class ClassCodegen {
|
|||||||
final InstructionAdapter iv = new InstructionAdapter(mv);
|
final InstructionAdapter iv = new InstructionAdapter(mv);
|
||||||
ExpressionCodegen codegen = new ExpressionCodegen(mv, bindingContext, frameMap, typeMapper, Type.VOID_TYPE, classDescriptor, kind);
|
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 + ";");
|
final Type classType = Type.getType("L" + classname + ";");
|
||||||
|
|
||||||
if (kind == OwnerKind.DELEGATING_IMPLEMENTATION) {
|
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 ITERATOR_NEXT_DESCRIPTOR = "()Ljava/lang/Object;";
|
||||||
private static final String INT_RANGE_CONSTRUCTOR_DESCRIPTOR = "(II)V";
|
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 ITERATOR_TYPE = Type.getType(Iterator.class);
|
||||||
private static final Type INT_RANGE_TYPE = Type.getType(IntRange.class);
|
private static final Type INT_RANGE_TYPE = Type.getType(IntRange.class);
|
||||||
private static final Type JET_OBJECT_TYPE = Type.getType(JetObject.class);
|
private static final Type JET_OBJECT_TYPE = Type.getType(JetObject.class);
|
||||||
@@ -501,11 +502,11 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
String fieldOwner;
|
String fieldOwner;
|
||||||
String interfaceOwner;
|
String interfaceOwner;
|
||||||
if (isInsideClass || isStatic) {
|
if (isInsideClass || isStatic) {
|
||||||
fieldOwner = interfaceOwner = JetTypeMapper.getOwner(propertyDescriptor, contextKind);
|
fieldOwner = interfaceOwner = typeMapper.getOwner(propertyDescriptor, contextKind);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fieldOwner = null;
|
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);
|
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));
|
v.load(0, JetTypeMapper.jetImplementationType(contextClass));
|
||||||
}
|
}
|
||||||
else if (contextKind == OwnerKind.DELEGATING_IMPLEMENTATION) {
|
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 {
|
else {
|
||||||
throw new UnsupportedOperationException("Unknown kind: " + contextKind);
|
throw new UnsupportedOperationException("Unknown kind: " + contextKind);
|
||||||
@@ -1242,11 +1243,35 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
@Override
|
@Override
|
||||||
public void visitBinaryWithTypeRHSExpression(JetBinaryExpressionWithTypeRHS expression) {
|
public void visitBinaryWithTypeRHSExpression(JetBinaryExpressionWithTypeRHS expression) {
|
||||||
JetSimpleNameExpression operationSign = expression.getOperationSign();
|
JetSimpleNameExpression operationSign = expression.getOperationSign();
|
||||||
if (operationSign.getReferencedNameElementType() == JetTokens.COLON) {
|
IElementType opToken = operationSign.getReferencedNameElementType();
|
||||||
|
if (opToken == JetTokens.COLON) {
|
||||||
gen(expression.getLeft());
|
gen(expression.getLeft());
|
||||||
}
|
}
|
||||||
else {
|
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(".", "/");
|
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) {
|
if (kind == OwnerKind.INTERFACE) {
|
||||||
return jvmNameForInterface(jetClass);
|
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) {
|
static Type psiClassType(PsiClass psiClass) {
|
||||||
return Type.getType("L" + jvmName(psiClass) + ";");
|
return Type.getType("L" + jvmName(psiClass) + ";");
|
||||||
}
|
}
|
||||||
@@ -84,7 +96,7 @@ public class JetTypeMapper {
|
|||||||
return jvmNameForInterface(descriptor) + "$$DImpl";
|
return jvmNameForInterface(descriptor) + "$$DImpl";
|
||||||
}
|
}
|
||||||
|
|
||||||
static String getOwner(DeclarationDescriptor descriptor, OwnerKind kind) {
|
public String getOwner(DeclarationDescriptor descriptor, OwnerKind kind) {
|
||||||
String owner;
|
String owner;
|
||||||
if (descriptor.getContainingDeclaration() instanceof NamespaceDescriptor) {
|
if (descriptor.getContainingDeclaration() instanceof NamespaceDescriptor) {
|
||||||
owner = jvmName((NamespaceDescriptor) descriptor.getContainingDeclaration());
|
owner = jvmName((NamespaceDescriptor) descriptor.getContainingDeclaration());
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ public class PropertyCodegen {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
iv.visitFieldInsn(kind == OwnerKind.NAMESPACE ? Opcodes.GETSTATIC : Opcodes.GETFIELD,
|
iv.visitFieldInsn(kind == OwnerKind.NAMESPACE ? Opcodes.GETSTATIC : Opcodes.GETFIELD,
|
||||||
JetTypeMapper.getOwner(propertyDescriptor, kind), propertyDescriptor.getName(),
|
mapper.getOwner(propertyDescriptor, kind), propertyDescriptor.getName(),
|
||||||
type.getDescriptor());
|
type.getDescriptor());
|
||||||
}
|
}
|
||||||
iv.areturn(type);
|
iv.areturn(type);
|
||||||
@@ -206,7 +206,7 @@ public class PropertyCodegen {
|
|||||||
else {
|
else {
|
||||||
iv.load(paramCode, type);
|
iv.load(paramCode, type);
|
||||||
iv.visitFieldInsn(kind == OwnerKind.NAMESPACE ? Opcodes.PUTSTATIC : Opcodes.PUTFIELD,
|
iv.visitFieldInsn(kind == OwnerKind.NAMESPACE ? Opcodes.PUTSTATIC : Opcodes.PUTFIELD,
|
||||||
JetTypeMapper.getOwner(propertyDescriptor, kind), propertyDescriptor.getName(),
|
mapper.getOwner(propertyDescriptor, kind), propertyDescriptor.getName(),
|
||||||
type.getDescriptor());
|
type.getDescriptor());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,5 +28,18 @@ public class TypeInfoTest extends CodegenTestCase {
|
|||||||
TypeInfo typeInfo = (TypeInfo) foo.invoke(null);
|
TypeInfo typeInfo = (TypeInfo) foo.invoke(null);
|
||||||
assertNotNull(typeInfo);
|
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