Roslyn заменяет синтаксические узлы в глубину - PullRequest
0 голосов
/ 06 апреля 2019

В качестве примера я хочу добавить XML-комментарии к классам, конструкторам и методам в cs-файле. Я пробую разные вещи, и все работает, когда я остаюсь в той же глубине SyntaxNode. Но следующий минимальный пример объявляет мою проблему.

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using System;
using System.Linq;

namespace Tools.Tester
{
    class Stackoverflow
    {
        public static void Question()
        {
            SyntaxTree tree = SyntaxFactory.ParseSyntaxTree(
            @"
            public class Class
            {
                public void Method(){}
            }
            "
            );

            //REPLACE CLASS
            SyntaxNode Class = tree.GetRoot().DescendantNodes().OfType<ClassDeclarationSyntax>().First();
            SyntaxNode ClassNew = Class.WithLeadingTrivia(SyntaxFactory.ParseLeadingTrivia("///<summery>XML</summery>").Add(SyntaxFactory.EndOfLine("\n")));

            /*CLASS SHOULD NOW:
            ///<summery>XML</summery>
            public class Class
            {
                public void Method(){}
            }
            */

            //REPLACE METHOD
            SyntaxNode Method = Class.DescendantNodes().OfType<MethodDeclarationSyntax>().First();
            SyntaxNode MethodNew = Method.WithLeadingTrivia(SyntaxFactory.ParseLeadingTrivia("///<summery>XML</summery>").Add(SyntaxFactory.EndOfLine("\n")));

            /*METHOD SHOULD NOW:
            ///<summery>XML</summery>
            public void Method(){}                
            */

            ClassNew = ClassNew.ReplaceNode(Method, MethodNew);
            /*CLASS SHOULD NOW:
            ///<summery>XML</summery>
            public class Class
            {
                ///<summery>XML</summery>
                public void Method(){}
            }
            */

            //UPDATE TREE
            SyntaxTree treeNew = SyntaxFactory.ParseSyntaxTree(tree.GetRoot().ReplaceNode(Class, ClassNew).GetText());
            string code = treeNew.GetText().ToString();
            Console.WriteLine(code);

            /*RESULT:
            ///<summery>XML</summery>
            public class Class
            {                
                public void Method(){}
            }
            */
        }
    }
}

Как обычно решить этот вариант использования? Кому я могу обновить класс SyntaxNode и метод SyntaxNode?

Спасибо за любой ответ!

Решение:

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using System;
using System.Linq;

namespace Tools.Tester
{
    class Stackoverflow
    {
        public static void Question()
        {
            SyntaxTree tree = SyntaxFactory.ParseSyntaxTree(
            @"
            public class Class
            {
                public void Method(){}
            }
            "
            );

            //REPLACE CLASS
            SyntaxNode Class = tree.GetRoot().DescendantNodes().OfType<ClassDeclarationSyntax>().First();
            SyntaxNode ClassNew = Class.WithLeadingTrivia(SyntaxFactory.ParseLeadingTrivia("///<summery>XML</summery>").Add(SyntaxFactory.EndOfLine("\n")));

            /*CLASS SHOULD NOW:
            ///<summery>XML</summery>
            public class Class
            {
                public void Method(){}
            }
            */

            //REPLACE METHOD CHANGE TO CLASS NEW HERE
            SyntaxNode Method = ClassNew.DescendantNodes().OfType<MethodDeclarationSyntax>().First();
            SyntaxNode MethodNew = Method.WithLeadingTrivia(SyntaxFactory.ParseLeadingTrivia("///<summery>XML</summery>").Add(SyntaxFactory.EndOfLine("\n")));

            /*METHOD SHOULD NOW:
            ///<summery>XML</summery>
            public void Method(){}                
            */

            ClassNew = ClassNew.ReplaceNode(Method, MethodNew);
            /*CLASS SHOULD NOW:
            ///<summery>XML</summery>
            public class Class
            {
                ///<summery>XML</summery>
                public void Method(){}
            }
            */

            //UPDATE TREE
            SyntaxTree treeNew = SyntaxFactory.ParseSyntaxTree(tree.GetRoot().ReplaceNode(Class, ClassNew).GetText());
            string code = treeNew.GetText().ToString();
            Console.WriteLine(code);

            /*RESULT:
            ///<summery>XML</summery>
            public class Class
            {                
                public void Method(){}
            }
            */
        }
    }
}
...