Try-catch-finally statements & correct line numbers

This commit is contained in:
Alexander Udalov
2012-11-22 17:35:30 +04:00
parent ca587513e3
commit 0f496eac21
8 changed files with 113 additions and 10 deletions
@@ -16,10 +16,7 @@
package org.jetbrains.jet.codegen;
import org.jetbrains.jet.lang.psi.JetElement;
import org.jetbrains.jet.lang.psi.JetIfExpression;
import org.jetbrains.jet.lang.psi.JetReturnExpression;
import org.jetbrains.jet.lang.psi.JetVisitor;
import org.jetbrains.jet.lang.psi.*;
public class CodegenStatementVisitor extends JetVisitor<StackValue, StackValue> {
private final ExpressionCodegen codegen;
@@ -37,4 +34,9 @@ public class CodegenStatementVisitor extends JetVisitor<StackValue, StackValue>
public StackValue visitIfExpression(JetIfExpression expression, StackValue receiver) {
return codegen.generateIfExpression(expression, true);
}
@Override
public StackValue visitTryExpression(JetTryExpression expression, StackValue data) {
return codegen.generateTryExpression(expression, true);
}
}
@@ -3146,6 +3146,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
@Override
public StackValue visitTryExpression(JetTryExpression expression, StackValue receiver) {
return generateTryExpression(expression, false);
}
public StackValue generateTryExpression(JetTryExpression expression, boolean isStatement) {
/*
The "returned" value of try expression with no finally is either the last expression in the try block or the last expression in the catch block
(or blocks).
@@ -3159,7 +3163,7 @@ The "returned" value of try expression with no finally is either the last expres
JetType jetType = bindingContext.get(BindingContext.EXPRESSION_TYPE, expression);
assert jetType != null;
Type expectedAsmType = asmType(jetType);
Type expectedAsmType = isStatement ? Type.VOID_TYPE : asmType(jetType);
Label tryStart = new Label();
v.mark(tryStart);
@@ -3167,8 +3171,11 @@ The "returned" value of try expression with no finally is either the last expres
gen(expression.getTryBlock(), expectedAsmType);
int savedValue = myFrameMap.enterTemp(expectedAsmType);
v.store(savedValue, expectedAsmType);
int savedValue = -1;
if (!isStatement) {
savedValue = myFrameMap.enterTemp(expectedAsmType);
v.store(savedValue, expectedAsmType);
}
Label tryEnd = new Label();
v.mark(tryEnd);
@@ -3196,7 +3203,9 @@ The "returned" value of try expression with no finally is either the last expres
gen(clause.getCatchBody(), expectedAsmType);
v.store(savedValue, expectedAsmType);
if (!isStatement) {
v.store(savedValue, expectedAsmType);
}
myFrameMap.leave(descriptor);
@@ -3231,10 +3240,14 @@ The "returned" value of try expression with no finally is either the last expres
v.visitTryCatchBlock(tryStart, tryEnd, finallyStart, null);
}
markLineNumber(expression);
v.mark(end);
v.load(savedValue, expectedAsmType);
myFrameMap.leaveTemp(expectedAsmType);
if (!isStatement) {
v.load(savedValue, expectedAsmType);
myFrameMap.leaveTemp(expectedAsmType);
}
if (finallyBlock != null) {
blockStackElements.pop();
@@ -0,0 +1,23 @@
fun z() {}
fun foo() {
try {
z()
} catch (e: Exception) {
z()
}
try {
z()
} finally {
z()
}
try {
z()
} catch (e: Exception) {
z()
} finally {
z()
}
}
@@ -0,0 +1,15 @@
fun foo() {
try {
System.out?.println()
} catch (e: Throwable) {
return
}
val t = try {
System.out?.println()
} catch (e: Throwable) {
return
}
}
// 2 3 5 8 9 11 8
@@ -0,0 +1,19 @@
fun foo() {
try {
System.out?.println()
} catch (e: Throwable) {
System.out?.println()
} finally {
System.out?.println()
}
val t = try {
System.out?.println()
} catch (e: Throwable) {
System.out?.println()
} finally {
System.out?.println()
}
}
// 2 3 7 5 7 10 11 15 13 15 10
@@ -0,0 +1,15 @@
fun foo() {
try {
System.out?.println()
} finally {
System.out?.println()
}
val t = try {
System.out?.println()
} finally {
System.out?.println()
}
}
// 2 3 5 8 9 11 8
@@ -303,6 +303,18 @@ public class LineNumberTest extends TestCaseWithTmpdir {
doTestCustom();
}
public void testTryCatchExpression() {
doTestCustom();
}
public void testTryCatchFinally() {
doTestCustom();
}
public void testTryFinally() {
doTestCustom();
}
public void testStaticDelegate() {
JetFile foo = createPsiFile("staticDelegate/foo.kt");
JetFile bar = createPsiFile("staticDelegate/bar.kt");
@@ -48,4 +48,8 @@ public class StatementGenTest extends CodegenTestCase {
public void testIfThenElseEmpty() {
doTest();
}
public void testTryCatchFinally() {
doTest();
}
}