How to remove a list of SyntaxNode from the Document using Roslyn code fix provider APIs?

ⅰ亾dé卋堺 提交于 2019-12-22 12:34:12

问题


I'm having a custom generated variable declaration using SyntaxFactory.VariableDeclaration and a list of SyntaxNode's collected according to some conditions.

I did the following:

  1. Modify the node

    var newRoot = root.ReplaceNode(expression, newVariableDeclaration)
    

    This successfully modified the node with the newVariableDeclaration.

  2. In a loop remove the nodes corresponding to the ones present in the list

    foreach (var listObject in listObjects)
    {
        newRoot = newRoot.RemoveNode(listObject, SyntaxRemoveOptions.KeepNoTrivia);
    }
    

    This doesn't change the newRoot and all the listObject required to be changed remains the same.

If we use root.RemoveNode(listObject, SyntaxRemoveOptions.KeepNoTrivia) instead it will, obviously, keep on replacing the previous changes.

So here the newVariableDeclaration is the only node that is changed in the whole document, is this because newRoot SyntaxNodes have changes from that of the SyntaxNode that I obtained from root.

Please correct me if I'm doing it wrong.

EDIT: I looked into CSharpSyntaxRewriter but it appears that it is analyzing a single node everytime it's visiting a node and can only modify a single node at a time. In my scenario, I'll have to visit a particular node, make changes to it, and remove other nodes with respect to the changes made to visited node.


回答1:


The problem with your approach is that whenever you change the tree (using ReplaceNode() or RemoveNode()), it means all the nodes change as well. This is why your calls to RemoveNode() after ReplaceNode() don't do anything.

One way to fix this is to use TrackNodes(), so that you can find which nodes in the modified tree correspond to nodes in the original tree.

Uisng this, a method that replaces a sequence of nodes with a single node could look like this:

public static T ReplaceNodes<T>(
    this T root, IReadOnlyList<SyntaxNode> oldNodes, SyntaxNode newNode)
    where T : SyntaxNode
{
    if (oldNodes.Count == 0)
        throw new ArgumentException();

    var newRoot = root.TrackNodes(oldNodes);

    var first = newRoot.GetCurrentNode(oldNodes[0]);

    newRoot = newRoot.ReplaceNode(first, newNode);

    var toRemove = oldNodes.Skip(1).Select(newRoot.GetCurrentNode);

    newRoot = newRoot.RemoveNodes(toRemove, SyntaxRemoveOptions.KeepNoTrivia);

    return newRoot;
}


来源:https://stackoverflow.com/questions/26505020/how-to-remove-a-list-of-syntaxnode-from-the-document-using-roslyn-code-fix-provi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!