2015-05-24 51 views
4

我正在编写一个代码分析器,它将if语句反转以减少嵌套。Roslyn在指定节点后插入节点

我能够生成一个新的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; 
} 
+0

这有点难(可能只是为了我)看看你想达到什么目的。你能提供一个你想要达到的事情吗? – JoshVarty

+0

正如@JoshVarty问之前/之后有一个例子。 – Gandarez

+0

你是怎么做@If语法的? – MHGameWork

回答

2

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

但是由于您首先替换了一个节点,新节点将完全在同一个地方。所以,你可以通过快捷键和FindNode,像这样:

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

我还没有测试此代码,但它应该工作。