コード例 #1
0
        private Block BuildTryStatement(TryStatementSyntax tryStatement, Block currentBlock)
        {
            // successor - either finally of next block after try statement
            var catchSuccessor = currentBlock;

            var hasFinally = tryStatement.Finally?.Block != null;

            if (hasFinally)
            {
                // Wire exit in case we have a return inside the try/catch block
                catchSuccessor = BuildBlock(tryStatement.Finally.Block,
                                            CreateBranchBlock(tryStatement.Finally, new[] { catchSuccessor, ExitTarget.Peek() }));

                ExitTarget.Push(catchSuccessor);
            }

            var catchBlocks = tryStatement.Catches
                              .Reverse()
                              .Select(catchClause => BuildBlock(catchClause.Block, CreateBlock(catchSuccessor)))
                              .ToList();

            // If there is a catch with no Exception filter or equivalent we don't want to
            // join the tryStatement start/end blocks with the exit block because all
            // exceptions will be caught before going to finally
            var areAllExceptionsCaught = tryStatement.Catches.Any(SyntaxHelper.IsCatchingAllExceptions);

            // try end
            var tryEndStatementConnections = catchBlocks.ToList();

            tryEndStatementConnections.Add(catchSuccessor); // happy path, no exceptions thrown
            if (!areAllExceptionsCaught)                    // unexpected exception thrown, go to exit (through finally if present)
            {
                tryEndStatementConnections.Add(ExitTarget.Peek());
            }

            var tryBody = BuildBlock(tryStatement.Block,
                                     CreateBranchBlock(tryStatement, tryEndStatementConnections.Distinct()));

            var tryStartStatementConnections = catchBlocks.ToList();

            tryStartStatementConnections.Add(tryBody); // try body

            if (!areAllExceptionsCaught)               // unexpected exception thrown, go to exit (through finally if present)
            {
                tryStartStatementConnections.Add(ExitTarget.Peek());
            }

            var tryStartBlock = CreateBranchBlock(tryStatement, tryStartStatementConnections.Distinct());

            if (hasFinally)
            {
                ExitTarget.Pop();
            }

            return(tryStartBlock);
        }
コード例 #2
0
 private Block BuildJumpToExitStatement(StatementSyntax statement, Block currentBlock, ExpressionSyntax expression = null)
 {
     return(BuildExpression(expression, CreateJumpBlock(statement, ExitTarget.Peek(), currentBlock)));
 }