Try-catch-finally statements & correct line numbers
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user