如何通过添加和删除从旧根检索到的节点来创建新根?

Jer*_*vel 12 c# roslyn

我正在创建一个代码修复程序来改变这个:

if(obj is MyClass)
{
    var castedObj = obj as MyClass;
}
Run Code Online (Sandbox Code Playgroud)

进入这个:

var castedObj = obj as MyClass;
if(castedObj != null)
{
}
Run Code Online (Sandbox Code Playgroud)

这意味着我必须做三件事:

  • 更改if语句中的条件.
  • 将演员移到if声明正上方.
  • 删除正文中的语句.

到目前为止,我所有的尝试都让我陷入困境,最多可以使这两件事情发挥作用.

我相信会出现此问题,因为您在同一级别上基本上有2个语法节点.因此,对其中一个进行更改会使另一个的位置无效.或类似的东西.简而言之:我要么设法在if语句之外复制变量赋值,要么我设法更改条件+删除变量赋值.绝不是全部3.

我该如何解决这个问题?

为了更好地衡量,这是我的代码,它更改条件并删除赋值:

var newIfStatement = ifStatement.RemoveNode(
                                   variableDeclaration,
                                   SyntaxRemoveOptions.KeepExteriorTrivia);
newIfStatement = newIfStatement.ReplaceNode(newIfStatement.Condition, newCondition);

var ifParent = ifStatement.Parent;
var newParent = ifParent.ReplaceNode(ifStatement, newIfStatement);
newParent = newParent.InsertNodesBefore(
                           newIfStatement, 
                           new[] { variableDeclaration })
                           .WithAdditionalAnnotations(Formatter.Annotation);

var newRoot = root.ReplaceNode(ifParent, newParent);
Run Code Online (Sandbox Code Playgroud)

Phi*_*ref 15

你看过DocumentEditor课吗?在处理修改语法时非常有用,尤其是当应用于树的更改可能导致失效问题时.操作与您已经定义的操作几乎相同,只需使用DocumentEditor方法,看看是否有帮助.我无法验证这是否解决了您的问题ATM,但我认为它曾经解决了我过去的类似问题.如果可以的话,我会稍后测试一下.

像这样的东西会这样做:

var editor = await DocumentEditor.CreateAsync(document);
editor.RemoveNode(variableDeclaration);
editor.ReplaceNode(ifStatement.Condition, newCondition);
editor.InsertBefore(ifStatement, 
     new[] { variableDeclaration.WithAdditionalAnnotations(Formatter.Annotation) });

var newDocument = editor.GetChangedDocument();
Run Code Online (Sandbox Code Playgroud)

  • 我希望我之前知道过那个类:没有不可变节点不能协同工作的麻烦.只需几行代码就可以替换上面的所有内容,而且读取的内容非常流畅.我将编辑你的答案,包括我以前完成的代码. (2认同)