c# - Roslyn 在指定节点后插入节点

标签 c# roslyn

我正在编写一个代码分析器,它反转 if 语句以减少嵌套。

我能够生成一个新的 if 节点并将其替换为文档根目录。但是,我必须将来自此 if 语句的所有内容(语句)移至其下方。让我展示一下我到目前为止所取得的成就:

var ifNode = @if;
var ifStatement = @if.Statement as BlockSyntax;
var returnNode = (ifNode.Parent as BlockSyntax).Statements.Last() as ReturnStatementSyntax ?? SyntaxFactory.ReturnStatement();
var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
var invertedIf = ifNode.WithCondition(Negate(ifNode.Condition, semanticModel, cancellationToken))
.WithStatement(returnNode)                
.WithAdditionalAnnotations(Formatter.Annotation);
var root = await document.GetSyntaxRootAsync(cancellationToken);
var newRoot = root.ReplaceNode(ifNode, invertedIf);
newRoot = newRoot.InsertNodesAfter(invertedIf, ifStatement.Statements); //It seems no to be working. There's no code after specified node.

return document.WithSyntaxRoot(newRoot);

之前:

public int Foo()
{
    if (true)
    {
        var a = 3;
        return a;
     }

     return 0;
}

之后:

public int Foo()
{
    if (false)
        return 0;

    var a = 3;
    return a;
}

最佳答案

Carlos,问题是在您 ReplaceNode 之后您生成了一个新节点。当你去 InsertNodeAfter 从原来的根节点传一个节点的时候,新节点找不到了。 在分析器中,您需要一次完成所有更改,或者注释或跟踪节点以便稍后返回。

但由于您是先替换节点,新节点将完全位于同一位置。所以你可以快捷方式和 FindNode,像这样:

newRoot = newRoot.InsertNodesAfter(newRoot.FindNode(ifNode.Span), ifStatement.Statements);

我还没有测试过这段代码,但它应该可以工作。

关于c# - Roslyn 在指定节点后插入节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30427741/

相关文章:

c# - 查找 Roslyn 默认可为 null 的上下文

c# - 使用 SQL 调用从数据库中检索数据后的特定 if else 语句。 Visual Studio 2015/C#

c# - 将ffmpeg流传递给c#窗口

c# - 使用这种类型的外部库后出现错误 "Type does not exist in the namespace"

c# - 如何禁用所有 Roslyn 代码分析器?

c# - 使用 ? 时出现编译器错误。导致无法通过 PEVerify 的不良图像

c# - 我可以在 VSIX 中检测到使用 Visual Studio Workspace 保存(未更改)的文档吗?

c# - 从没有反射的c#源代码中提取属性

c# - 来自 C# 的 javascript unicode 属性

c# - 如何在 Active Directory 中获取/更新 'Contacts'?