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)); }
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); }
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)) })))); }
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); }