Sto tentando di sostituire un paio di nodi in un albero di sintassi utilizzando roslyn. Ma la natura immutabile sembra mettersi sulla mia strada.Sostituzione di più nodi nell'albero di sintassi di 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();
}
Il problema è che quando chiamo root.ReplaceNodes
solo alcuni dei nodi viene sostituito.
Immagino che la sostituzione cambi l'albero in modo che gli altri nodi non corrispondano più all'albero originale e quindi non possono essere sostituiti.
Ma qual è il modo migliore per affrontare questo?
Looping sul processo più e più volte fino a non più il cambiamento si verifica sente zoppo :)
I cambiamenti possono avvenire annidati, e penso che è ciò che provoca i problemi qui. Posso ordinare il changeset in qualche modo per aggirare questo o c'è un modo idiomatico di fare le cose qui?