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