Replacing multiple nodes in a Roslyn syntax tree

I am trying to replace a pair of nodes in a syntax tree with roslyn. But the immutable nature of this seems to bother me.

public static string Rewrite(string content) { var tree = CSharpSyntaxTree.ParseText(content); var root = tree.GetRoot(); var methods =root .DescendantNodes(node=>true) .OfType<MethodDeclarationSyntax>() .ToList(); foreach(var method in methods) { var returnActions = method .DescendantNodes(node => true) .OfType<BinaryExpressionSyntax>() //Ok this is cheating .Where(node => node.OperatorToken.ValueText == "==") .Where(node => node.Right.ToString() == "\"#exit#\"" || node.Right.ToString() == "\"#break#\"") .Select(node => node.Parent as IfStatementSyntax) .ToList(); var lookup = new Dictionary<StatementSyntax,StatementSyntax>(); if (returnActions.Count > 0) { foreach(var ifStatement in returnActions) { var mainCall = ifStatement.GetPrevious() as ExpressionStatementSyntax; var newIfStatement = ifStatement.WithCondition(mainCall.Expression.WithoutTrivia()); lookup[mainCall] = null; lookup[ifStatement] = newIfStatement; } //this only replace some of the nodes root = root.ReplaceNodes(lookup.Keys, (s, d) => lookup[s]); } } return root.ToFullString(); } 

The problem is that when you call root.ReplaceNodes only some of the nodes are replaced.

I assume that the replacement changes the tree so that other nodes no longer correspond to the original tree and therefore can be replaced.

But what is the best way to handle this?

Repeating the process for and until more changes occur is lame :)

Changes can occur nested, and I think that this is where the problems arise. Can I sort the set of changes anyway to get around this or is there an idiomatic way to do it here?

+7
c # roslyn
source share
1 answer

I assume that the replacement changes the tree so that other nodes no longer correspond to the original tree and therefore can be replaced.

You're right. Replacing nodes creates completely new syntax trees. Nodes from previous syntax trees cannot be compared with these new syntax trees.

There are four ways to apply a few changes to the syntax tree:

Of these options, I find DocumentEditor be the easiest to use. It is possible that an idiomatic way of applying several changes in the future.

+11
source share

All Articles