【问题标题】:Roslyn to insert nodes after specified nodeRoslyn 在指定节点之后插入节点
【发布时间】:2015-05-24 19:58:10
【问题描述】:

我正在编写一个代码分析器,它反转 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;
}

【问题讨论】:

  • 看到你想要达到的目标有点困难(也许只是对我来说)。您能否提供您想要实现的目标的前后对比?
  • 正如@JoshVarty 所问的,有一个之前/之后的例子。
  • @If 语法你是怎么做的?

标签: c# roslyn


【解决方案1】:

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多