Reputation: 2662
I'm writing a code analyzer which inverts an if statement to reduce nesting.
I'm able to generate a new if node and replace it to the document root. However I must move all content(statements) coming from this if statement to below it. Let me show what I've achieved so far:
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);
Before:
public int Foo()
{
if (true)
{
var a = 3;
return a;
}
return 0;
}
After:
public int Foo()
{
if (false)
return 0;
var a = 3;
return a;
}
Upvotes: 4
Views: 2597
Reputation: 839
Carlos, the problem is that after you ReplaceNode
you generated a new node. When you go InsertNodeAfter
and pass a node from the original root node, the new node can't find it.
In an analyzer you need to either do all the changes at once, or annotate or track the nodes so you can come back to them later.
But since you are replacing a node first, the new node will be exactly at the same place. So you can shortcut and FindNode
, like this:
newRoot = newRoot.InsertNodesAfter(newRoot.FindNode(ifNode.Span), ifStatement.Statements);
I haven't tested this code, but it should work.
Upvotes: 2