问题
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:
Modify the node
var newRoot = root.ReplaceNode(expression, newVariableDeclaration)
This successfully modified the node with the
newVariableDeclaration
.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 thelistObject
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