Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

658
Vistas
Replacing multiple nodes in Roslyn syntax tree

I'm trying to replace a couple of nodes in a syntax tree using roslyn. But the immutable nature of it seems to get in my way.

    public static string Rewrite(string content)
    {
        var tree = CSharpSyntaxTree.ParseText(content);
        var root = tree.GetRoot();

        var methods =root
            .DescendantNodes(node=>true)
            .OfType<MethodDeclarationSyntax>()
            .ToList();

        foreach(var method in methods)
        {
            var returnActions = method
                .DescendantNodes(node => true)
                .OfType<BinaryExpressionSyntax>()
                //Ok this is cheating
                .Where(node => node.OperatorToken.ValueText == "==")
                .Where(node => node.Right.ToString() == "\"#exit#\"" || node.Right.ToString() == "\"#break#\"")
                .Select(node => node.Parent as IfStatementSyntax)
                .ToList();

            var lookup = new Dictionary<StatementSyntax,StatementSyntax>();

            if (returnActions.Count > 0)
            {
                foreach(var ifStatement in returnActions)
                {
                    var mainCall = ifStatement.GetPrevious() as ExpressionStatementSyntax;                        
                    var newIfStatement = ifStatement.WithCondition(mainCall.Expression.WithoutTrivia());

                    lookup[mainCall] = null;
                    lookup[ifStatement] = newIfStatement;
                }

                //this only replace some of the nodes
                root = root.ReplaceNodes(lookup.Keys, (s, d) => lookup[s]);
            }
        }

        return root.ToFullString();
    }

The problem is that when I call root.ReplaceNodes only some of the nodes gets replaced.

I guess that the replacement changes the tree so that the other nodes no longer match the original tree and thus cant be replaced.

But what is the best way to deal with this?

Looping over the process over and over untill no more change occurs feels lame :)

The changes can occur nested, and I think that is what causes the problems here. Can I sort the changeset somehow to get around this or is there an idiomatic way to go about things here?

over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

I guess that the replacement changes the tree so that the other nodes no longer match the original tree and thus cant be replaced.

You're right. Replacing nodes creates entirely new syntax trees. Nodes from previous syntax trees cannot be compared against these new syntax trees.

There are four ways to apply multiple changes to a syntax tree:

  1. Use the DocumentEditor - See: https://stackoverflow.com/a/30563669/300908
  2. Use Annotations (Lines 236 and 240)
  3. Use .TrackNodes()
  4. Create a CSharpSyntaxRewriter that replaces nodes in a bottom-up approach. I've written about this on my blog.

Of these options, I believe the DocumentEditor has the reputation for being the easiest to use. It may very well be the idiomatic way to apply multiple changes going forward.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda