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; package org.jetbrains.jet.codegen;
import org.jetbrains.jet.lang.psi.JetElement; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.psi.JetIfExpression;
import org.jetbrains.jet.lang.psi.JetReturnExpression;
import org.jetbrains.jet.lang.psi.JetVisitor;
public class CodegenStatementVisitor extends JetVisitor<StackValue, StackValue> { public class CodegenStatementVisitor extends JetVisitor<StackValue, StackValue> {
private final ExpressionCodegen codegen; private final ExpressionCodegen codegen;
@@ -37,4 +34,9 @@ public class CodegenStatementVisitor extends JetVisitor<StackValue, StackValue>
public StackValue visitIfExpression(JetIfExpression expression, StackValue receiver) { public StackValue visitIfExpression(JetIfExpression expression, StackValue receiver) {
return codegen.generateIfExpression(expression, true); 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 @Override
public StackValue visitTryExpression(JetTryExpression expression, StackValue receiver) { 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 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). (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); JetType jetType = bindingContext.get(BindingContext.EXPRESSION_TYPE, expression);
assert jetType != null; assert jetType != null;
Type expectedAsmType = asmType(jetType); Type expectedAsmType = isStatement ? Type.VOID_TYPE : asmType(jetType);
Label tryStart = new Label(); Label tryStart = new Label();
v.mark(tryStart); 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); gen(expression.getTryBlock(), expectedAsmType);
int savedValue = myFrameMap.enterTemp(expectedAsmType); int savedValue = -1;
v.store(savedValue, expectedAsmType); if (!isStatement) {
savedValue = myFrameMap.enterTemp(expectedAsmType);
v.store(savedValue, expectedAsmType);
}
Label tryEnd = new Label(); Label tryEnd = new Label();
v.mark(tryEnd); 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); gen(clause.getCatchBody(), expectedAsmType);
v.store(savedValue, expectedAsmType); if (!isStatement) {
v.store(savedValue, expectedAsmType);
}
myFrameMap.leave(descriptor); 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); v.visitTryCatchBlock(tryStart, tryEnd, finallyStart, null);
} }
markLineNumber(expression);
v.mark(end); v.mark(end);
v.load(savedValue, expectedAsmType); if (!isStatement) {
myFrameMap.leaveTemp(expectedAsmType); v.load(savedValue, expectedAsmType);
myFrameMap.leaveTemp(expectedAsmType);
}
if (finallyBlock != null) { if (finallyBlock != null) {
blockStackElements.pop(); 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(); doTestCustom();
} }
public void testTryCatchExpression() {
doTestCustom();
}
public void testTryCatchFinally() {
doTestCustom();
}
public void testTryFinally() {
doTestCustom();
}
public void testStaticDelegate() { public void testStaticDelegate() {
JetFile foo = createPsiFile("staticDelegate/foo.kt"); JetFile foo = createPsiFile("staticDelegate/foo.kt");
JetFile bar = createPsiFile("staticDelegate/bar.kt"); JetFile bar = createPsiFile("staticDelegate/bar.kt");
@@ -48,4 +48,8 @@ public class StatementGenTest extends CodegenTestCase {
public void testIfThenElseEmpty() { public void testIfThenElseEmpty() {
doTest(); doTest();
} }
public void testTryCatchFinally() {
doTest();
}
} }