Замена нескольких узлов в синтаксическом дереве Roslyn
Я пытаюсь заменить пару узлов в синтаксическом дереве, используя Roslyn. Но непреложная природа этого, кажется, мешает мне.
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();
}
Проблема в том, что когда я звонюroot.ReplaceNodes
только некоторые из узлов заменяются.
Я предполагаю, что замена изменяет дерево так, что другие узлы больше не соответствуют исходному дереву и, следовательно, не могут быть заменены.
Но как лучше всего с этим справиться?
Зацикливаясь на процессе снова и снова, пока не произойдет больше изменений, я чувствую себя хромым :)
Изменения могут происходить вложенными, и я думаю, что именно здесь возникают проблемы. Могу ли я как-то отсортировать ревизию, чтобы обойти это, или есть какой-то идиотский способ сделать это?