c# visual-studio-2013 roslyn vsix

c# - ¿Cómo eliminar una lista de SyntaxNode del documento utilizando las API del proveedor de arreglos de código Roslyn?



visual-studio-2013 vsix (1)

Tengo una declaración de variable generada de forma personalizada utilizando SyntaxFactory.VariableDeclaration y una lista de SyntaxNode recopilada según algunas condiciones.

Hice lo siguiente:

  1. Modificar el nodo

    var newRoot = root.ReplaceNode(expression, newVariableDeclaration)

    Esto modificó correctamente el nodo con la newVariableDeclaration .

  2. En un bucle, elimine los nodos correspondientes a los que están en la lista

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

    Esto no cambia el newRoot y todo el listObject requerido para ser cambiado sigue siendo el mismo.

Si usamos root.RemoveNode(listObject, SyntaxRemoveOptions.KeepNoTrivia) , obviamente continuará reemplazando los cambios anteriores.

Así que aquí la newVariableDeclaration es el único nodo que se cambia en todo el documento, esto es porque newRoot SyntaxNodes tiene cambios de la del SyntaxNode que obtuve desde la root .

Por favor corrígeme si lo estoy haciendo mal.

EDITAR: busqué en CSharpSyntaxRewriter pero parece que está analizando un solo nodo cada vez que visita un nodo y solo puede modificar un solo nodo a la vez. En mi caso, tendré que visitar un nodo en particular, realizar cambios en él y eliminar otros nodos con respecto a los cambios realizados en el nodo visitado.


El problema con su enfoque es que cada vez que cambie el árbol (utilizando ReplaceNode() o RemoveNode() ), significa que todos los nodos cambian también. Es por eso que sus llamadas a RemoveNode() después de ReplaceNode() no hacen nada.

Una forma de solucionar esto es usar TrackNodes() , para que pueda encontrar qué nodos en el árbol modificado corresponden a nodos en el árbol original.

De esta forma, un método que reemplaza una secuencia de nodos con un solo nodo podría verse así:

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; }