Skip to content

Improve SyntaxFactory for documentation comments #218

@sharwell

Description

@sharwell

This request is best described by a motivating example.

In a recent code fix, I wanted to add the following documentation comment to a class:

/// <summary>
/// This class provides extension methods for the <see cref="TypeName"/> class.
/// </summary>
/// <threadsafety static="true" instance="false"/>
/// <preliminary/>

This is the way I found to implement it:

DocumentationCommentTriviaSyntax documentationComment = SyntaxFactory.DocumentationCommentTrivia(SyntaxKind.SingleLineDocumentationCommentTrivia)
    .AddContent(
        SyntaxFactory.XmlElement(
            SyntaxFactory.XmlElementStartTag(SyntaxFactory.XmlName("summary")),
            SyntaxFactory.List<XmlNodeSyntax>()
                .Add(
                    SyntaxFactory.XmlText().AddTextTokens(
                        SyntaxFactory.XmlTextNewLine(SyntaxFactory.TriviaList(), Environment.NewLine, Environment.NewLine, SyntaxFactory.TriviaList()),
                        SyntaxFactory.XmlTextLiteral(SyntaxFactory.TriviaList(), "This class provides extension methods for the ", "This class provides extension methods for the ", SyntaxFactory.TriviaList())
                            .WithLeadingTrivia(SyntaxFactory.DocumentationCommentExterior("/// "))))
                .Add(
                    SyntaxFactory.XmlEmptyElement(SyntaxFactory.XmlName("see")).AddAttributes(
                        SyntaxFactory.XmlCrefAttribute(
                            SyntaxFactory.XmlName("cref"),
                            SyntaxFactory.Token(SyntaxKind.DoubleQuoteToken),
                            SyntaxFactory.TypeCref(SyntaxFactory.ParseTypeName(declaringType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat))),
                            SyntaxFactory.Token(SyntaxKind.DoubleQuoteToken))
                            .WithLeadingTrivia(SyntaxFactory.Whitespace(" "))))
                .Add(
                    SyntaxFactory.XmlText().AddTextTokens(
                        SyntaxFactory.XmlTextLiteral(SyntaxFactory.TriviaList(), " class.", " class.", SyntaxFactory.TriviaList()),
                        SyntaxFactory.XmlTextNewLine(SyntaxFactory.TriviaList(), Environment.NewLine, Environment.NewLine, SyntaxFactory.TriviaList()))),
            SyntaxFactory.XmlElementEndTag(SyntaxFactory.XmlName("summary"))
                .WithLeadingTrivia(SyntaxFactory.DocumentationCommentExterior("/// "))),
        SyntaxFactory.XmlText().AddTextTokens(SyntaxFactory.XmlTextNewLine(SyntaxFactory.TriviaList(), Environment.NewLine, Environment.NewLine, SyntaxFactory.TriviaList())),
        SyntaxFactory.XmlEmptyElement(SyntaxFactory.XmlName("threadsafety"))
            .AddAttributes(
                SyntaxFactory.XmlTextAttribute(
                    SyntaxFactory.XmlName("static"),
                    SyntaxFactory.Token(SyntaxKind.DoubleQuoteToken),
                    SyntaxFactory.TokenList(SyntaxFactory.XmlTextLiteral(SyntaxFactory.TriviaList(), "true", "true", SyntaxFactory.TriviaList())),
                    SyntaxFactory.Token(SyntaxKind.DoubleQuoteToken))
                    .WithLeadingTrivia(SyntaxFactory.Whitespace(" ")),
                SyntaxFactory.XmlTextAttribute(
                    SyntaxFactory.XmlName("instance"),
                    SyntaxFactory.Token(SyntaxKind.DoubleQuoteToken),
                    SyntaxFactory.TokenList(SyntaxFactory.XmlTextLiteral(SyntaxFactory.TriviaList(), "false", "false", SyntaxFactory.TriviaList())),
                    SyntaxFactory.Token(SyntaxKind.DoubleQuoteToken))
                    .WithLeadingTrivia(SyntaxFactory.Whitespace(" ")))
            .WithLeadingTrivia(SyntaxFactory.DocumentationCommentExterior("/// ")),
        SyntaxFactory.XmlText().AddTextTokens(SyntaxFactory.XmlTextNewLine(SyntaxFactory.TriviaList(), Environment.NewLine, Environment.NewLine, SyntaxFactory.TriviaList())),
        SyntaxFactory.XmlEmptyElement(SyntaxFactory.XmlName("preliminary"))
            .WithLeadingTrivia(SyntaxFactory.DocumentationCommentExterior("/// ")))
    .WithLeadingTrivia(SyntaxFactory.DocumentationCommentExterior("/// "))
    .WithTrailingTrivia(SyntaxFactory.EndOfLine(Environment.NewLine));

I then had to attach the comment to the ClassDeclarationSyntax using the following transform:

.WithLeadingTrivia(SyntaxFactory.TriviaList(SyntaxFactory.Trivia(documentationComment)))

Metadata

Metadata

Assignees

No one assigned

    Labels

    Area-CompilersConcept-APIThis issue involves adding, removing, clarification, or modification of an API.Feature Requesthelp wantedThe issue is "up for grabs" - add a comment if you are interested in working on it

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions