2013-04-24 3 views
6

В настоящее время я работаю над трехсторонним слиянием синтаксических деревьев с использованием Roslyn. У меня есть соответствие между всеми дочерними элементами на узле ClassDeclerationSyntax и вы хотите выполнить слияние с дочерними элементами, а затем создать новое дерево на основе этого слияния.Замена нескольких узлов в одном и том же дереве, используя SyntaxNode.ReplaceNode

O - вход ClassDeclerationSyntax, и соответствие имеет три элемента (A, O, B) типа 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); 
} 

Это не работает. На второй итерации ReplaceNode возвращает полностью немодифицированный узел (oldUpdated == updated - true).

Похоже, что после первой итерации цикла все дети были реконструированы как новые объекты, а исходные дочерние объекты, сохраненные в моем сопоставлении, больше не могут быть найдены в списке детей (updated.ChildNodes().Where(x => x == m.O) пуст).

Что было бы хорошим способом сделать это?

+0

Я считаю, что вы должны быть в состоянии сделать это с помощью аннотаций. – svick

ответ

6

Мой текущий подход:

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()); 
+0

Это правильный подход. –

 Смежные вопросы

  • Нет связанных вопросов^_^