2015-05-24 78 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); 

我還沒有測試此代碼,但它應該工作。