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