C# Roslyn analyzer代码修复提供程序替换文档中的字符串
我已经识别了一个节点,该节点的字符串中有一个值,我的分析器可以正确识别该值。然后我创建了一个CodeFixProvider,它可以成功地检索字符串,然后我想替换字符串的某个部分。现在我想替换文档中的字符串以修复警告。如何最好地应用此修复程序C# Roslyn analyzer代码修复提供程序替换文档中的字符串,c#,roslyn,roslyn-code-analysis,C#,Roslyn,Roslyn Code Analysis,我已经识别了一个节点,该节点的字符串中有一个值,我的分析器可以正确识别该值。然后我创建了一个CodeFixProvider,它可以成功地检索字符串,然后我想替换字符串的某个部分。现在我想替换文档中的字符串以修复警告。如何最好地应用此修复程序 public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { var root = await context.Docum
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
}
公共密封覆盖异步任务注册表CodeFixesAsync(CodeFixContext上下文)
{
var root=await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);
var diagnostic=context.Diagnostics.First();
var diagnosticSpan=diagnostic.Location.SourceSpan;
//查找诊断所标识的类型声明。
var declaration=root.FindToken(diagnosticSpan.Start).Parent.antestorsandself().OfType().First();
//注册将调用修复程序的代码操作。
context.RegisterCodeFix(
代码动作。创建(
标题:正则表达式,
createChangedSolution:c=>ReplaceRegexAsync(context.Document,声明,c),
等价键:regex),
诊断性);
}
专用异步任务ReplaceRegexAsync(文档文档、文字表达式Syntax typeDecl、CancellationToken CancellationToken)
{
var identifierToken=typeDecl.Token;
var updatedText=identifierToken.Text.Replace(“myword”、“另一个Word”);
//Todo如何替换原始文本以应用修复
}
- 最好不要使用
签名,而使用CodeAction。使用
创建createChangedSolution
。它允许在解决方案中注册修补单个文档的修复程序createChangedDocument
- 您需要通过修改
或SyntaxTree
SourceText
。。。
context.RegisterCodeFix(
代码动作。创建(
标题:正则表达式,
createChangedDocument:c=>ReplaceRegexAsync(context.Document,声明,c),
等价键:regex),
诊断性);
专用异步任务ReplaceRegexAsync(文档文档、文字表达式Syntax typeDecl、CancellationToken CancellationToken)
{
var identifierToken=typeDecl.Token;
var updatedText=identifierToken.Text.Replace(“myword”、“另一个Word”);
var valueText=identifierToken.valueText.Replace(“myword”、“另一个Word”);
var newToken=SyntaxFactory.Literal(identifierToken.LeadingTrivia、UpdateText、valueText、identifierToken.TrailingTrivia);
var sourceText=await typeDecl.SyntaxTree.GetTextAsync(cancellationToken);
//通过更改源文本更新文档
返回document.WithText(sourceText.WithChanges(newtextchange(identifierToken.FullSpan,newToken.ToFullString()));
}
createChangedDocument优于createChangedSolution的依据是什么?@jmoreno,主要目标是您不必关心创建(修补)具有createChangedSolution
签名的新项目和新解决方案,因为VisualStudio在通过createChangedSolution
签名接收结果时自己完成这项工作
...
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())));
}