diff --git a/Source/ReferenceTests/Language/TryCatchFinallyTests.cs b/Source/ReferenceTests/Language/TryCatchFinallyTests.cs
new file mode 100644
index 00000000..c74d5ca4
--- /dev/null
+++ b/Source/ReferenceTests/Language/TryCatchFinallyTests.cs
@@ -0,0 +1,40 @@
+using System;
+using NUnit.Framework;
+
+namespace ReferenceTests.Language
+{
+ [TestFixture]
+ public class TryCatchFinallyTests : ReferenceTestBase
+ {
+ [Test]
+ public void TryFinallyWithoutCatch()
+ {
+ ExecuteAndCompareTypedResult(
+ "try { 2 + 2 } finally { 0 }",
+ 4,
+ 0
+ );
+ }
+
+ [Test]
+ public void TryCatchFinally()
+ {
+ ExecuteAndCompareTypedResult(
+ "try { 2 + 2 } catch { -1 } finally { 0 }",
+ 4,
+ 0
+ );
+ }
+
+ [Test]
+ public void TryCatchFinallyWithException()
+ {
+ ExecuteAndCompareTypedResult(
+ "try { 2 / 0 } catch { -1 } finally { 3 }",
+ -1,
+ 3
+ );
+ }
+ }
+}
+
diff --git a/Source/ReferenceTests/ReferenceTests.csproj b/Source/ReferenceTests/ReferenceTests.csproj
index 200087fc..6d59f245 100644
--- a/Source/ReferenceTests/ReferenceTests.csproj
+++ b/Source/ReferenceTests/ReferenceTests.csproj
@@ -132,6 +132,7 @@
+
diff --git a/Source/System.Management/Pash/Implementation/ExecutionVisitor.cs b/Source/System.Management/Pash/Implementation/ExecutionVisitor.cs
index 337f0f74..e64c11ba 100644
--- a/Source/System.Management/Pash/Implementation/ExecutionVisitor.cs
+++ b/Source/System.Management/Pash/Implementation/ExecutionVisitor.cs
@@ -1322,8 +1322,16 @@ public override AstVisitAction VisitTryStatement(TryStatementAst tryStatementAst
{
SetUnderscoreVariable(ex);
+ // not yet considered: no catches, special catches!
tryStatementAst.CatchClauses.Last().Body.Visit(this);
}
+ finally
+ {
+ if (tryStatementAst.Finally != null)
+ {
+ tryStatementAst.Finally.Visit(this);
+ }
+ }
return AstVisitAction.SkipChildren;
}
diff --git a/Source/System.Management/Pash/ParserIntrinsics/AstBuilder.cs b/Source/System.Management/Pash/ParserIntrinsics/AstBuilder.cs
index dafa2bdb..b3b37552 100644
--- a/Source/System.Management/Pash/ParserIntrinsics/AstBuilder.cs
+++ b/Source/System.Management/Pash/ParserIntrinsics/AstBuilder.cs
@@ -424,11 +424,20 @@ private StatementAst BuildBreakStatementAst(ParseTreeNode parseTreeNode)
StatementAst BuildTryStatementAst(ParseTreeNode parseTreeNode)
{
+ var subClauses = parseTreeNode.ChildNodes[0].ChildNodes;
+ var catchClauses = subClauses[2];
+ var finallyClause = subClauses.Count > 3 ? subClauses[3] : null;
+ // there might be no catch clauses, then a finally clause could follow directly
+ if (catchClauses.Term == this._grammar.finally_clause)
+ {
+ finallyClause = catchClauses;
+ catchClauses = null;
+ }
return new TryStatementAst(
new ScriptExtent(parseTreeNode),
- BuildStatementBlockAst(parseTreeNode.ChildNodes[0].ChildNodes[1]),
- BuildCatchClausesAst(parseTreeNode.ChildNodes[0].ChildNodes[2]),
- null
+ BuildStatementBlockAst(subClauses[1]),
+ catchClauses == null ? Enumerable.Empty() : BuildCatchClausesAst(catchClauses),
+ finallyClause == null ? null : BuildFinallyClauseAst(finallyClause)
);
}
@@ -452,6 +461,13 @@ private CatchClauseAst BuildCatchClauseAst(ParseTreeNode parseTreeNode)
);
}
+ StatementBlockAst BuildFinallyClauseAst(ParseTreeNode finallyClause)
+ {
+ VerifyTerm(finallyClause, this._grammar.finally_clause);
+
+ return BuildStatementBlockAst(finallyClause.ChildNodes[1]);
+ }
+
StatementAst BuildDataStatementAst(ParseTreeNode parseTreeNode)
{
throw new NotImplementedException();