Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/273.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Roslyn analyzer代码修复提供程序替换文档中的字符串_C#_Roslyn_Roslyn Code Analysis - Fatal编程技术网

C# Roslyn analyzer代码修复提供程序替换文档中的字符串

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

我已经识别了一个节点,该节点的字符串中有一个值,我的分析器可以正确识别该值。然后我创建了一个CodeFixProvider,它可以成功地检索字符串,然后我想替换字符串的某个部分。现在我想替换文档中的字符串以修复警告。如何最好地应用此修复程序

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