Example #1
0
        private static void CreateAndPlaceDisposeCallAfterLastUsage(string variableName, BlockSyntax parentBlock,
                                                                    StatementSyntax lastUsageStatement, SyntaxEditor editor)
        {
            var disposeCall = SyntaxCreator.CreateDisposeCallFor(variableName);

            var statementsBeforeLastUsage = parentBlock.Statements
                                            .TakeWhile(s => s != lastUsageStatement);
            var statementsAfterLastUsage = parentBlock.Statements
                                           .SkipWhile(s => s != lastUsageStatement)
                                           .Skip(1);

            var newBlock = SyntaxFactory.Block(
                statementsBeforeLastUsage
                .Concat(lastUsageStatement)
                .Concat(disposeCall)
                .Concat(statementsAfterLastUsage)
                ).WithoutAnnotations(Formatter.Annotation);

            editor.ReplaceNode(parentBlock, newBlock);
        }
Example #2
0
        private static ExpressionStatementSyntax CreateDisposeCall(string memberName, bool castToIDisposable)
        {
            if (castToIDisposable)
            {
                return(SyntaxFactory.ExpressionStatement(
                           SyntaxFactory.ConditionalAccessExpression(
                               SyntaxFactory.ParenthesizedExpression(
                                   SyntaxFactory.BinaryExpression(
                                       SyntaxKind.AsExpression,
                                       SyntaxFactory.IdentifierName(memberName),
                                       SyntaxFactory.IdentifierName(Constants.IDisposable))
                                   .WithOperatorToken(
                                       SyntaxFactory.Token(SyntaxKind.AsKeyword)))
                               .WithOpenParenToken(
                                   SyntaxFactory.Token(SyntaxKind.OpenParenToken))
                               .WithCloseParenToken(
                                   SyntaxFactory.Token(SyntaxKind.CloseParenToken)),
                               SyntaxFactory.InvocationExpression(
                                   SyntaxFactory.MemberBindingExpression(
                                       SyntaxFactory.IdentifierName(Constants.Dispose))
                                   .WithOperatorToken(
                                       SyntaxFactory.Token(SyntaxKind.DotToken)))
                               .WithArgumentList(
                                   SyntaxFactory.ArgumentList()
                                   .WithOpenParenToken(
                                       SyntaxFactory.Token(SyntaxKind.OpenParenToken))
                                   .WithCloseParenToken(
                                       SyntaxFactory.Token(SyntaxKind.CloseParenToken))))
                           .WithOperatorToken(
                               SyntaxFactory.Token(SyntaxKind.QuestionToken)))
                       .WithSemicolonToken(
                           SyntaxFactory.Token(SyntaxKind.SemicolonToken)));
            }

            return(SyntaxCreator.CreateConditionalAccessDisposeCallFor(memberName));
        }
        private static async Task <Document> Apply(CodeFixContext context, CancellationToken cancel)
        {
            var editor = await DocumentEditor.CreateAsync(context.Document, cancel);

            var node         = editor.OriginalRoot.FindNode(context.Span);
            var variableName = FindVariableName(node);

            if (node.TryFindContainigBlock(out var parentBlock))
            {
                var lastUsage = parentBlock
                                .DescendantNodes <VariableDeclaratorSyntax>()
                                .Last(ins => ins.Identifier.Text == variableName);
                if (lastUsage.TryFindParent <StatementSyntax>(parentBlock, out var lastUsageStatement))
                {
                    var disposeCall = SyntaxCreator.CreateDisposeCallFor(variableName);

                    var statementsBeforeLastUsage = parentBlock.Statements
                                                    .TakeWhile(s => s != lastUsageStatement);
                    var statementsAfterLastUsage = parentBlock.Statements
                                                   .SkipWhile(s => s != lastUsageStatement)
                                                   .Skip(1);

                    var newBlock = SyntaxFactory.Block(
                        statementsBeforeLastUsage
                        .Concat(lastUsageStatement)
                        .Concat(disposeCall)
                        .Concat(statementsAfterLastUsage)
                        ).WithoutAnnotations(Formatter.Annotation);
                    editor.ReplaceNode(parentBlock, newBlock);

                    return(editor.GetChangedDocument());
                }
            }

            return(context.Document);
        }