Replacing several nodes in the same tree, using SyntaxNode.ReplaceNode
c#, roslyn
Solution
My current approach:
var updateMember = new Dictionary<MemberDeclarationSyntax, MemberDeclarationSyntax>();
var addMembers = new List<MemberDeclarationSyntax>();
foreach (var m in matching) {
if (m.A != null && m.B != null && m.O != null) {
var mergeChild = Merge(m.A, m.B, M.O);
updateMember.Add(m.O, child);
}
else if (m.A == null && m.O == null && m.B != null)
addMembers.Add(m.B);
else if (m.A != null && m.O == null && m.B == null)
addMembers.Add(m.A);
}
var merged = O.ReplaceNodes(updateMember.Keys.AsEnumerable(), (n1, n2) =>
{
return updateMember[n1];
}).AddMembers(addMembers.ToArray());
Problem
I'm currently working on three-way merging on syntax trees using Roslyn. I have a matching between all children on a a `ClassDeclerationSyntax` node, and want to perform a merge on the children, and then create a new tree based on that merge. O is the input `ClassDeclerationSyntax`, and matching has three members (A, O, B) of the type `MemberDeclerationSyntax`. ``` var updated = O; foreach (var m in matching) { if (m.A != null && m.B != null && m.O != null) { var merge = Merge(m.A, m.O, m.B); var oldUpdated = updated; updated = updated.ReplaceNode(m.O, merge); } else if (m.A == null && m.O == null && m.B != null) updated = updated.AddMembers(m.B); else if (m.A != null && m.O == null && m.B == null) updated = updated.AddMembers(m.A); } ``` This does not work. In the second iteration `ReplaceNode` returns a completely unmodified node (`oldUpdated == updated` is `true`). It seems that after the first iteration of the loop, all children have been reconstructed as new objects, and the original children-objects stored in my matching can no longer be found in the children list (`updated.ChildNodes().Where(x => x == m.O)` is empty). What would a good way be to do this?