Reputation: 1446
I have identified a node that has a value in its string which my Analyzer correctly identifies. I have then created a CodeFixProvider that can successfully retrieve the string and I then want to replace a certain part of the string. I now want to replace the string in the document to fix the warning. How can I best apply this fix?
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
{
var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);
var diagnostic = context.Diagnostics.First();
var diagnosticSpan = diagnostic.Location.SourceSpan;
// Find the type declaration identified by the diagnostic.
var declaration = root.FindToken(diagnosticSpan.Start).Parent.AncestorsAndSelf().OfType<LiteralExpressionSyntax>().First();
// Register a code action that will invoke the fix.
context.RegisterCodeFix(
CodeAction.Create(
title: regex,
createChangedSolution: c => ReplaceRegexAsync(context.Document, declaration, c),
equivalenceKey: regex),
diagnostic);
}
private async Task<Solution> ReplaceRegexAsync(Document document, LiteralExpressionSyntax typeDecl, CancellationToken cancellationToken)
{
var identifierToken = typeDecl.Token;
var updatedText = identifierToken.Text.Replace("myword", "anotherword");
// Todo how to replace original text to apply fix
}
Upvotes: 0
Views: 733
Reputation: 2936
CodeAction.Create
signature with createChangedSolution
, but createChangedDocument
.It allows to register fix that patch a single document in solution.SyntaxTree
or SourceText
...
context.RegisterCodeFix(
CodeAction.Create(
title: regex,
createChangedDocument:c => ReplaceRegexAsync(context.Document, declaration, c),
equivalenceKey: regex),
diagnostic);
private async Task<Document> ReplaceRegexAsync(Document document, LiteralExpressionSyntax typeDecl, CancellationToken cancellationToken)
{
var identifierToken = typeDecl.Token;
var updatedText = identifierToken.Text.Replace("myword", "anotherword");
var valueText = identifierToken.ValueText.Replace("myword", "anotherword");
var newToken = SyntaxFactory.Literal(identifierToken.LeadingTrivia, updatedText, valueText, identifierToken.TrailingTrivia);
var sourceText = await typeDecl.SyntaxTree.GetTextAsync(cancellationToken);
// update document by changing the source text
return document.WithText(sourceText.WithChanges(new TextChange(identifierToken.FullSpan, newToken.ToFullString())));
}
Upvotes: 1