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?