6

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?

1
  • I believe you should be able to do this using annotations. Commented Apr 24, 2013 at 14:22

1 Answer 1

8

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());
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.