我正在编写一个代码分析器,它反转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;
}
答案 0 :(得分:2)
Carlos,问题是在ReplaceNode
之后你生成了一个新节点。当您转到InsertNodeAfter
并从原始根节点传递节点时,新节点无法找到它。
在分析器中,您需要一次完成所有更改,或者注释或跟踪节点,以便稍后再返回。
但是,由于您首先要替换节点,因此新节点将完全位于同一位置。所以你可以快捷方式FindNode
,像这样:
newRoot = newRoot.InsertNodesAfter(newRoot.FindNode(ifNode.Span), ifStatement.Statements);
我还没有测试过这段代码,但它应该有用。