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?
c # roslyn
Roger Johansson
source share