How to add XML Comments to a MethodDeclarationSyntax node using Roslyn?

2k views Asked by At

I am trying to add XML comments to C# code as a code fix using the Roslyn compiler and Microsoft's CodeAnalysis API. So far I have been able to figure out how to change current XML comments of a MethodDeclarationSyntax.

I retrieve the DocumentationCommentTriviaSyntax from the MethodDeclarationSyntax. Since these objects are immutable I make a new DocumentationCommentTriviaSyntax with the content of my old comment as will as my new comment using SyntaxFactory.DocumentationCommentTrivia. Then I make a new root for the syntax tree replacing my old DocumentationCommentTriviaSyntax with my new one using root.ReplaceNode. Then I create a new document using this new root and return it.

But I can't seem to figure out how to add an XML comment if there is none to begin with and have been unable to find any documentation to help me. If there is no comment to begin with, my DocumentationCommentTriviaSyntax is null and ReplaceNode throws an error.

Can someone point me in the right direction? I appreciate the help in advance!

1

There are 1 answers

1
m0sa On BEST ANSWER

You need to modify your MethodDeclarationSyntax and call ReplaceNode with it.

So let's say we have the following documentation trivia:

var testDocumentation = SyntaxFactory.DocumentationCommentTrivia(
    SyntaxKind.SingleLineDocumentationCommentTrivia,
    SyntaxFactory.List<XmlNodeSyntax>(
        new XmlNodeSyntax[]{
            SyntaxFactory.XmlText()
            .WithTextTokens(
                SyntaxFactory.TokenList(
                    SyntaxFactory.XmlTextLiteral(
                        SyntaxFactory.TriviaList(
                            SyntaxFactory.DocumentationCommentExterior("///")),
                        " ",
                        " ",
                        SyntaxFactory.TriviaList()))),
            SyntaxFactory.XmlElement(
                SyntaxFactory.XmlElementStartTag(
                    SyntaxFactory.XmlName(
                        SyntaxFactory.Identifier("summary"))),
                SyntaxFactory.XmlElementEndTag(
                    SyntaxFactory.XmlName(
                        SyntaxFactory.Identifier("summary"))))
            .WithContent(
                SyntaxFactory.SingletonList<XmlNodeSyntax>(
                    SyntaxFactory.XmlText()
                    .WithTextTokens(
                        SyntaxFactory.TokenList(
                            SyntaxFactory.XmlTextLiteral(
                                SyntaxFactory.TriviaList(),
                                "test",
                                "test",
                                SyntaxFactory.TriviaList()))))),
            SyntaxFactory.XmlText()
            .WithTextTokens(
                SyntaxFactory.TokenList(
                    SyntaxFactory.XmlTextNewLine(
                        SyntaxFactory.TriviaList(),
                        "\n",
                        "\n",
                        SyntaxFactory.TriviaList())))}));

... and we have a public static void Main() method that we want to add documentation to. It already has trivia (but not necessarily):

SyntaxFactory.TokenList(
    new []{
        SyntaxFactory.Token(SyntaxKind.PublicKeyword),
        SyntaxFactory.Token(SyntaxKind.StaticKeyword)}));

We need to wrap the first token's content in that list (I'll leave that to you to do programatically..) in a new trivia list:

var newMethodNode = oldMethodNode.WithModifiers(
    SyntaxFactory.TokenList(
        new []{
            SyntaxFactory.Token(
                SyntaxFactory.TriviaList(
                    SyntaxFactory.Trivia(testDocumentation)), // xmldoc
                    SyntaxKind.PublicKeyword, // original 1st token
                    SyntaxFactory.TriviaList()),
            SyntaxFactory.Token(SyntaxKind.StaticKeyword)}))

root.ReplaceNode (oldMethodNode, newMethodNode);

To figure out exactly what to trivia to construct, use RoslynQuoter.