how to recover references to old syntax nodes after syntaxtree transformation?

Topics: APIs, General
May 29 at 12:35 PM
Hi,
I need to transform all properties of a class.
So first, I visit all the properties and store the references.
But, when I transform a property, because I add new fields to the class, the class mutates,
And now all the references to the other properties are not valid in the new tree for the class..

What is the recommended way to do this?
It seems to me a little inefficient to revisit the whole class, and either way I cannot detect the property nodes already handled due to the reference difference....

Is there a recommended way to do something like this?

Thanks...
May 29 at 10:02 PM
Edited May 29 at 10:02 PM
I'm not sure that's the best/recommended way, but you can use IsEquivalentTo method to check if given syntax node from new tree is equivalent to one from old tree.
May 29 at 11:41 PM
Edited May 29 at 11:43 PM
The easiest thing would be to derive from CSharpSyntaxRewriter as it correctly handles the situation you're describing:
using System;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;

internal class Program
{
    private static void Main(string[] args)
    {
        var code = @"
class X
{
    public int X1 {get;set;}
    public float X2 {get;set;}
}
";

        var parsed = SyntaxFactory.ParseCompilationUnit(code);
        var rewriter = new PropertyRewriter();
        var rewritten = rewriter.Visit(parsed);

        Console.WriteLine(rewritten);

        // Output:
        // class X
        // {
        //      public int X1Changed {get;set;}
        //      public float X2Changed {get;set;}
        // }
    }

    private class PropertyRewriter : CSharpSyntaxRewriter
    {
        public override SyntaxNode VisitPropertyDeclaration(PropertyDeclarationSyntax node)
        {
            return node.WithIdentifier(SyntaxFactory.Identifier(
                 node.Identifier.ValueText + "Changed") // Codeplex bug, should be a plus...
                    .WithLeadingTrivia(node.Identifier.LeadingTrivia)
                    .WithTrailingTrivia(node.Identifier.TrailingTrivia));
        }
    }
}
May 30 at 12:20 AM
Edited May 30 at 7:11 AM
Hi, thanks marcinjuraszek very much.
IsEquivalentTo method looked perfect for my needs, but unfortunatelly does not work for me.
I had to roll up my own version of checking for equivalency...