Esempio n. 1
0
        public override SyntaxNode VisitTryStatement(TryStatementSyntax node)
        {
            // Do not add an OperationCanceledException catch block if:
            // - there are no catch blocks (only finally)
            // - there already exists an OperationCanceledException catch block
            // - there are no ancestors of OperationCanceledException being catched
            // - there are no async calls that have a cancellation token argument and there are no guards added
            if (node.Catches.Count == 0 ||
                node.Catches.Any(o => o.Declaration != null && SkipExceptions.Contains(o.Declaration.Type.ToString())) ||
                node.Catches.All(o => o.Declaration != null && !IncludeExceptions.Contains(o.Declaration.Type.ToString())) ||
                !node.Block.DescendantNodes(o => !o.IsFunction()).Any(o => o.HasAnnotations(Annotations.AsyncCallWithTokenOrGuard)))
            {
                return(base.VisitTryStatement(node));
            }

            var catchClause = CatchClause()
                              .WithCatchKeyword(
                Token(TriviaList(node.GetLeadingTrivia().LastOrDefault(o => o.IsKind(SyntaxKind.WhitespaceTrivia))), SyntaxKind.CatchKeyword, TriviaList(Space)))
                              .WithDeclaration(
                CatchDeclaration(_namespaceMetadata.UsingSystem
                                                        ? IdentifierName(nameof(OperationCanceledException))
                                                        : SyntaxNodeExtensions.ConstructNameSyntax($"System.{nameof(OperationCanceledException)}"))
                .WithCloseParenToken(Token(TriviaList(), SyntaxKind.CloseParenToken, TriviaList(Space))))
                              .WithBlock(
                Block(SingletonList <StatementSyntax>(
                          ThrowStatement().WithSemicolonToken(Token(TriviaList(), SyntaxKind.SemicolonToken, TriviaList(Space)))
                          ))
                .WithOpenBraceToken(Token(TriviaList(), SyntaxKind.OpenBraceToken, TriviaList(Space)))
                .WithCloseBraceToken(Token(TriviaList(), SyntaxKind.CloseBraceToken, TriviaList(_eolTrivia)))
                );

            node = node.WithCatches(new SyntaxList <CatchClauseSyntax>(new[] { catchClause }.Concat(node.Catches)));
            return(base.VisitTryStatement(node));
        }
Esempio n. 2
0
        public override SyntaxNode VisitTryStatement(TryStatementSyntax node)
        {
            node = (TryStatementSyntax)base.VisitTryStatement(node);

            List <CatchClauseSyntax> catches = new List <CatchClauseSyntax>();
            var replace = false;

            foreach (var catchItem in node.Catches)
            {
                var newCatch = catchItem;

                if (catchItem.Filter != null)
                {
                    var filter = catchItem.Filter;

                    var ifStatement = SyntaxFactory.IfStatement(filter.FilterExpression, catchItem.Block.WithoutTrivia(), SyntaxFactory.ElseClause(SyntaxFactory.ThrowStatement().WithLeadingTrivia(SyntaxFactory.Space)));
                    newCatch = catchItem.WithBlock(SyntaxFactory.Block(ifStatement)).WithFilter(null);
                    replace  = true;
                }

                catches.Add(newCatch);
            }

            return(replace ? node.WithCatches(SyntaxFactory.List(catches)) : node);
        }
Esempio n. 3
0
 public static TryStatementSyntax WithCatch(this TryStatementSyntax tryStatement, TypeSyntax exceptionType, string exceptionIdentifier, params StatementSyntax[] statements)
 {
     return(tryStatement
            .WithCatches(SyntaxFactory.List(tryStatement.Catches.Concat(new[]
     {
         SyntaxFactory.CatchClause()
         .WithDeclaration(SyntaxFactory.CatchDeclaration(exceptionType, SyntaxFactory.Identifier(exceptionIdentifier)))
         .WithBlock(Block(statements))
     }))));
 }
Esempio n. 4
0
        public override SyntaxNode VisitTryStatement(TryStatementSyntax node)
        {
            // Goal: Inject instruction counter, but also inject an auto catcher for all exceptions that have been marked
            // as unblockable in the compiler.

            var blockResumeLocation     = GetBlockResumeLocation(node.Block);
            var successiveBlockLocation = GetBlockResumeLocation((SyntaxNode)node.Catches.FirstOrDefault() ?? node.Finally);
            var catchClauseLocations    = node.Catches.Select(c => GetBlockResumeLocation(c.Block)).ToArray();
            var finallyLocation         = node.Finally != null?GetBlockResumeLocation(node.Finally.Block) : new FileLinePositionSpan();

            node = (TryStatementSyntax)base.VisitTryStatement(node);

            node = node.WithBlock(InjectedBlock(node.Block, blockResumeLocation));

            var catches = new SyntaxList <CatchClauseSyntax>();

            foreach (var exceptionType in m_compiler.UnblockableIngameExceptions)
            {
                catches = catches.Add(Barricaded(successiveBlockLocation.Path, successiveBlockLocation.StartLinePosition, SyntaxFactory.CatchClause(
                                                     SyntaxFactory.CatchDeclaration(AnnotatedIdentifier(exceptionType.FullName)),
                                                     null,
                                                     SyntaxFactory.Block(
                                                         SyntaxFactory.ThrowStatement())
                                                     )));
            }

            for (var i = 0; i < node.Catches.Count; i++)
            {
                var catchClause    = node.Catches[i];
                var resumeLocation = catchClauseLocations[i];
                catches = catches.Add(catchClause.WithBlock(InjectedBlock(catchClause.Block, resumeLocation)));
            }

            node = node.WithCatches(catches);

            if (node.Finally != null)
            {
                node = node.WithFinally(node.Finally.WithBlock(InjectedBlock(node.Finally.Block, finallyLocation)));
            }

            return(node);
        }