Roslyn IfStatement

chu*_*ley 1 c# roslyn

我正在使用Roslyn语法树来更新if/else语句.这是我的代码:

foreach (StatementSyntax statement in blockNode.Statements)
{
    if (statement.IsKind(SyntaxKind.IfStatement))
    {
        BlockSyntax ifBlock = statement.ChildNodes().OfType<BlockSyntax>().FirstOrDefault();
        if (ifBlock != null)
        {
            ReturnStatementSyntax newRSS = ifBlock.ChildNodes().OfType<ReturnStatementSyntax>().FirstOrDefault();
            blockNode = blockNode.InsertNodesBefore(newRSS, newExitCode);
        }
        ElseClauseSyntax elseBlock = statement.ChildNodes().OfType<ElseClauseSyntax>().FirstOrDefault();
        if (elseBlock != null)
        {
            BlockSyntax block = elseBlock.ChildNodes().OfType<BlockSyntax>().FirstOrDefault();
            if (block != null)
            {
                ReturnStatementSyntax newRSS = block.ChildNodes().OfType<ReturnStatementSyntax>().FirstOrDefault();
                blockNode = blockNode.InsertNodesBefore(newRSS, newExitCode);
            }
        }
        newBlock = newBlock.AddRange(blockNode.Statements);
    }
}
Run Code Online (Sandbox Code Playgroud)

任何人都可以解释为什么第一个blockNode插入节点工作,但第二个没有?我看到我想要插入的代码两次,但只有第一个更新语法树.第二个什么也没做.

更新:我已经做出了JoshVarty建议的更改.我使用DocumentEditor加载更改.我在调用GetChangedDocument时遇到异常.这是我的代码:

DocumentEditor editor = DocumentEditor.CreateAsync(doc).Result;
editor.InsertBefore(blockNode, newEntryCode);
editor.InsertAfter(blockNode, newExitCode);
Document newDoc = editor.GetChangedDocument();
Run Code Online (Sandbox Code Playgroud)

例外情况是:Microsoft.CodeAnalysis.CSharp.dll中出现"System.InvalidOperationException"类型的异常,但未在用户代码中处理

附加信息:指定的项目不是列表的元素.

我必须使用发电机吗?我错过了什么?

谢谢

Jos*_*rty 6

我相信这里的问题是你从中创建一个新树statement,然后尝试使用那个新树的部分进行比较statement.

基本上这条线第二次没有做任何事情:

blockNode = blockNode.InsertNodesBefore(newRSS, newExitCode);
Run Code Online (Sandbox Code Playgroud)

blockNode是一个你创建并且不包含的全新树newRSS.所以它无法找到newRss并插入你的newExitCode.

  • newRss 来自 block
  • block 来自 elseBlock
  • elseBlock 是从原来的 statement

尝试一次将多个更改应用于语法树时,有三个选项:

  1. 使用DocumentEditor- 请参阅:https://stackoverflow.com/a/30563669/300908
  2. 使用Annotations(第235和239行)
  3. 使用 .TrackNodes()

我的理解是DocumentEditor最简单的选择,并负责在封面下为您跟踪/注释节点.