diff --git a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index e6faecf1c8d..e97b0529bd2 100644 --- a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -53,7 +53,7 @@ public class ExpressionCodegen extends JetVisitor { private final FrameMap myMap; private final JetTypeMapper typeMapper; private final Type returnType; - private final ClassDescriptor contextType; + private final DeclarationDescriptor contextType; private final OwnerKind contextKind; private final BindingContext bindingContext; @@ -62,7 +62,7 @@ public class ExpressionCodegen extends JetVisitor { FrameMap myMap, JetTypeMapper typeMapper, Type returnType, - ClassDescriptor contextType, + DeclarationDescriptor contextType, OwnerKind contextKind) { this.myMap = myMap; this.typeMapper = typeMapper; @@ -1194,17 +1194,60 @@ public class ExpressionCodegen extends JetVisitor { throw new UnsupportedOperationException("Cannot generate this expression in top level context"); } + ClassDescriptor contextClass = (ClassDescriptor) contextType; if (contextKind == OwnerKind.IMPLEMENTATION) { - v.load(0, JetTypeMapper.jetImplementationType(contextType)); + v.load(0, JetTypeMapper.jetImplementationType(contextClass)); } else if (contextKind == OwnerKind.DELEGATING_IMPLEMENTATION) { - v.getfield(JetTypeMapper.jvmName(contextType, contextKind), "$this", JetTypeMapper.jetInterfaceType(contextType).getDescriptor()); + v.getfield(JetTypeMapper.jvmName(contextClass, contextKind), "$this", JetTypeMapper.jetInterfaceType(contextClass).getDescriptor()); } else { throw new UnsupportedOperationException("Unknown kind: " + contextKind); } } + @Override + public void visitTryExpression(JetTryExpression expression) { + if (expression.getFinallyBlock() != null) { + throw new UnsupportedOperationException("finally block in try/catch not yet supported"); + } + Label tryStart = new Label(); + v.mark(tryStart); + gen(expression.getTryBlock(), Type.VOID_TYPE); + Label tryEnd = new Label(); + v.mark(tryEnd); + Label end = new Label(); + v.goTo(end); // TODO don't generate goto if there's no code following try/catch + for (JetCatchClause clause : expression.getCatchClauses()) { + Label clauseStart = new Label(); + v.mark(clauseStart); + + VariableDescriptor descriptor = bindingContext.getVariableDescriptor(clause.getCatchParameter()); + Type descriptorType = typeMapper.mapType(descriptor.getOutType()); + myMap.enter(descriptor, 1); + int index = myMap.getIndex(descriptor); + v.store(index, descriptorType); + + gen(clause.getCatchBody(), Type.VOID_TYPE); + v.goTo(end); // TODO don't generate goto if there's no code following try/catch + + myMap.leave(descriptor); + v.visitTryCatchBlock(tryStart, tryEnd, clauseStart, descriptorType.getInternalName()); + } + v.mark(end); + } + + @Override + public void visitBinaryWithTypeRHSExpression(JetBinaryExpressionWithTypeRHS expression) { + JetSimpleNameExpression operationSign = expression.getOperationSign(); + if (operationSign.getReferencedNameElementType() == JetTokens.COLON) { + gen(expression.getLeft()); + } + else { + throw new UnsupportedOperationException("should generate a cast, but don't know how"); + } + } + private static class CompilationException extends RuntimeException { } } diff --git a/idea/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/idea/src/org/jetbrains/jet/codegen/FunctionCodegen.java index 74eba882f04..e45f4a34e6d 100644 --- a/idea/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -1,6 +1,7 @@ package org.jetbrains.jet.codegen; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; @@ -46,7 +47,9 @@ public class FunctionCodegen { boolean isAbstract = kind == OwnerKind.INTERFACE || bodyExpression == null; if (isAbstract) flags |= Opcodes.ACC_ABSTRACT; - ClassDescriptor ownerClass = owner instanceof JetClass ? bindingContext.getClassDescriptor((JetClass) owner) : null; + DeclarationDescriptor contextDescriptor = owner instanceof JetClass + ? bindingContext.getClassDescriptor((JetClass) owner) + : bindingContext.getNamespaceDescriptor((JetNamespace) owner); final MethodVisitor mv = v.visitMethod(flags, jvmSignature.getName(), jvmSignature.getDescriptor(), null, null); if (kind != OwnerKind.INTERFACE) { @@ -63,7 +66,7 @@ public class FunctionCodegen { frameMap.enter(parameter, argTypes[i].getSize()); } - ExpressionCodegen codegen = new ExpressionCodegen(mv, bindingContext, frameMap, typeMapper, jvmSignature.getReturnType(), ownerClass, kind); + ExpressionCodegen codegen = new ExpressionCodegen(mv, bindingContext, frameMap, typeMapper, jvmSignature.getReturnType(), contextDescriptor, kind); if (kind instanceof OwnerKind.DelegateKind) { OwnerKind.DelegateKind dk = (OwnerKind.DelegateKind) kind; InstructionAdapter iv = new InstructionAdapter(mv); diff --git a/idea/tests/org/jetbrains/jet/codegen/ControlStructuresTest.java b/idea/tests/org/jetbrains/jet/codegen/ControlStructuresTest.java index c4f2fdd30c1..bf183752557 100644 --- a/idea/tests/org/jetbrains/jet/codegen/ControlStructuresTest.java +++ b/idea/tests/org/jetbrains/jet/codegen/ControlStructuresTest.java @@ -103,8 +103,9 @@ public class ControlStructuresTest extends CodegenTestCase { public void testTryCatch() throws Exception { loadFile("tryCatch.jet"); + System.out.println(generateToText()); final Method main = generateFunction(); assertEquals("no message", main.invoke(null, "0")); - assertEquals("xxx", main.invoke(null, "a")); + assertEquals("For input string: \"a\"", main.invoke(null, "a")); } }