diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenStatementVisitor.java b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenStatementVisitor.java index df66c45e6a0..ac16828fdbd 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenStatementVisitor.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenStatementVisitor.java @@ -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 { private final ExpressionCodegen codegen; @@ -37,4 +34,9 @@ public class CodegenStatementVisitor extends JetVisitor 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); + } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index baf4b58540c..76ddfef5633 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -3146,6 +3146,10 @@ public class ExpressionCodegen extends JetVisitor 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(); diff --git a/compiler/testData/codegen/statements/tryCatchFinally.kt b/compiler/testData/codegen/statements/tryCatchFinally.kt new file mode 100644 index 00000000000..4dd0d8472bd --- /dev/null +++ b/compiler/testData/codegen/statements/tryCatchFinally.kt @@ -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() + } +} diff --git a/compiler/testData/lineNumber/custom/tryCatchExpression.kt b/compiler/testData/lineNumber/custom/tryCatchExpression.kt new file mode 100644 index 00000000000..eee47b7b032 --- /dev/null +++ b/compiler/testData/lineNumber/custom/tryCatchExpression.kt @@ -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 diff --git a/compiler/testData/lineNumber/custom/tryCatchFinally.kt b/compiler/testData/lineNumber/custom/tryCatchFinally.kt new file mode 100644 index 00000000000..5bbdfc0e70d --- /dev/null +++ b/compiler/testData/lineNumber/custom/tryCatchFinally.kt @@ -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 diff --git a/compiler/testData/lineNumber/custom/tryFinally.kt b/compiler/testData/lineNumber/custom/tryFinally.kt new file mode 100644 index 00000000000..2ccad419548 --- /dev/null +++ b/compiler/testData/lineNumber/custom/tryFinally.kt @@ -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 diff --git a/compiler/tests/org/jetbrains/jet/codegen/LineNumberTest.java b/compiler/tests/org/jetbrains/jet/codegen/LineNumberTest.java index fe85c3182b4..013ec029621 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/LineNumberTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/LineNumberTest.java @@ -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"); diff --git a/compiler/tests/org/jetbrains/jet/codegen/StatementGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/StatementGenTest.java index 583418e6337..41907edf79b 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/StatementGenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/StatementGenTest.java @@ -48,4 +48,8 @@ public class StatementGenTest extends CodegenTestCase { public void testIfThenElseEmpty() { doTest(); } + + public void testTryCatchFinally() { + doTest(); + } }