【问题标题】:Roslyn analyzer code fix provider replace string in documentRoslyn 分析器代码修复提供程序替换文档中的字符串
【发布时间】:2019-11-28 10:36:00
【问题描述】:

我已识别出一个节点,该节点的字符串中包含我的分析器正确识别的值。然后我创建了一个可以成功检索字符串的 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
    }

【问题讨论】:

    标签: c# roslyn roslyn-code-analysis


    【解决方案1】:
    • 最好不要使用CodeAction.Create 签名和createChangedSolution,而是createChangedDocument。它允许在解决方案中注册修补单个文档的修复程序。
    • 您需要通过修改SyntaxTreeSourceText 将更改应用到文档
    ...
    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())));
    }
    

    【讨论】:

    • 说createChangedDocument优于createChangedSolution的依据是什么?
    • @jmoreno,主要目标是您无需关心使用createChangedSolution 签名创建(修补)新项目和新解决方案,因为VisualStudio 在收到@987654328 的结果时会自行完成@签名
    猜你喜欢
    • 1970-01-01
    • 2021-10-28
    • 2015-07-17
    • 2020-01-11
    • 2015-10-12
    • 1970-01-01
    • 1970-01-01
    • 2020-11-11
    • 1970-01-01
    相关资源
    最近更新 更多