Skip to content
This repository has been archived by the owner on Feb 4, 2019. It is now read-only.

Support for "finally" clauses #413

Merged
merged 2 commits into from
Mar 26, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions Source/ReferenceTests/Language/TryCatchFinallyTests.cs
Original file line number Diff line number Diff line change
@@ -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
);
}
}
}

1 change: 1 addition & 0 deletions Source/ReferenceTests/ReferenceTests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@
<Compile Include="TestUtil.cs" />
<Compile Include="Commands\ConvertToSecureStringTests.cs" />
<Compile Include="Language\ExpressionTests.cs" />
<Compile Include="Language\TryCatchFinallyTests.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\System.Management\System.Management.csproj">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
22 changes: 19 additions & 3 deletions Source/System.Management/Pash/ParserIntrinsics/AstBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -424,11 +424,20 @@ private StatementAst BuildBreakStatementAst(ParseTreeNode parseTreeNode)

StatementAst BuildTryStatementAst(ParseTreeNode parseTreeNode)
{
var subClauses = parseTreeNode.ChildNodes[0].ChildNodes;
var catchClauses = subClauses[2];
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to the grammar, the 3rd element of the specific parseTree is either a "finally_clause" or "catch_clauses" sub tree. The latter one has multiple childs representing multiple cacth clauses.

The following functions care about finding the concrete catch clauses in the "sub tree".
However, multiple catch clauses are not yet evaluated correctly, see #414.

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<CatchClauseAst>() : BuildCatchClausesAst(catchClauses),
finallyClause == null ? null : BuildFinallyClauseAst(finallyClause)
);
}

Expand All @@ -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();
Expand Down