2014-10-22 2 views
2

У меня есть объявление сгенерированной переменной с использованием SyntaxFactory.VariableDeclaration и список SyntaxNode собран в соответствии с некоторыми условиями.Как удалить список SyntaxNode из документа с использованием API-интерфейсов поставщика кода Roslyn?

я сделал следующее:

  1. Изменить Узел

    var newRoot = root.ReplaceNode(expression, newVariableDeclaration) 
    

    Это успешно модифицированному узел с newVariableDeclaration.

  2. В цикле удалить узлы, соответствующие тем, которые присутствуют в списке

    foreach (var listObject in listObjects) 
    { 
        newRoot = newRoot.RemoveNode(listObject, SyntaxRemoveOptions.KeepNoTrivia); 
    } 
    

    Это не меняет newRoot, и все необходимое для listObject быть изменен остается тем же самым.

Если мы используем root.RemoveNode(listObject, SyntaxRemoveOptions.KeepNoTrivia) вместо этого он будет, очевидно, держать на замене предыдущих изменений.

Так вот newVariableDeclaration является только узел, который изменяется во всем документе, это потому, что newRootSyntaxNodes есть изменения от такового в SyntaxNode, что я получил от root.

Пожалуйста, исправьте меня, если я сделаю это неправильно.

EDIT: Я посмотрел в CSharpSyntaxRewriter, но оказывается, что он анализирует один узел каждый раз он посещает узел и может изменить только один узел одновременно. В моем сценарии мне придется посетить определенный узел, внести в него изменения и удалить другие узлы в отношении изменений, внесенных в посещаемый узел.

ответ

1

Проблема с вашим подходом заключается в том, что всякий раз, когда вы меняете дерево (используя ReplaceNode() или RemoveNode()), это означает, что все узлы тоже меняются. Вот почему ваши звонки на RemoveNode() после ReplaceNode() ничего не делают.

Один из способов исправить это - использовать TrackNodes(), чтобы вы могли найти, какие узлы в модифицированном дереве соответствуют узлам исходного дерева.

Uisng это способ, который заменяет последовательность узлов с одним узлом может выглядеть следующим образом:

public static T ReplaceNodes<T>(
    this T root, IReadOnlyList<SyntaxNode> oldNodes, SyntaxNode newNode) 
    where T : SyntaxNode 
{ 
    if (oldNodes.Count == 0) 
     throw new ArgumentException(); 

    var newRoot = root.TrackNodes(oldNodes); 

    var first = newRoot.GetCurrentNode(oldNodes[0]); 

    newRoot = newRoot.ReplaceNode(first, newNode); 

    var toRemove = oldNodes.Skip(1).Select(newRoot.GetCurrentNode); 

    newRoot = newRoot.RemoveNodes(toRemove, SyntaxRemoveOptions.KeepNoTrivia); 

    return newRoot; 
}