Merge remote branch 'origin/master'

This commit is contained in:
Andrey Breslav
2011-05-13 13:49:14 +04:00
3 changed files with 54 additions and 7 deletions
@@ -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 {
}
}
@@ -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);
@@ -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"));
}
}