简体   繁体   English

如何在 Roslyn 中向 ClassDeclarationSyntax 添加 XML 文档注释?

[英]How do I add an XML Doc Comment to a ClassDeclarationSyntax in Roslyn?

I have some code that builds a class:我有一些构建类的代码:

return SyntaxFactory
    .ClassDeclaration(name)
    .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword))
    .WithMembers(GetProperties());

This all works, and outputs the class that I expect.这一切都有效,并输出我期望的类。 I'd like to add an XML doc to this:我想为此添加一个 XML 文档:

/// <summary>
/// Some plain text here.
/// </summary>

I don't need anything fancy, just plain text.我不需要任何花哨的东西,只需要纯文本。 I'm struggling to find any examples of this, and have been through various overloads of Annotations , Trivia , and loads of methods hanging off SyntaxFactory ( XmlComment , XmlElementStartTag , DocumentationCommentExterior , DocumentationCommentTrivia ) with no joy (ironically, none of these have XML Comments!).我正在努力寻找这方面的任何示例,并且经历了AnnotationsTrivia各种重载以及SyntaxFactoryXmlCommentXmlElementStartTagDocumentationCommentExteriorDocumentationCommentTrivia )的各种重载,但没有任何乐趣(具有讽刺意味的是,这些都没有 XML 注释!)。 The closest I got was something that compiled, but crashed at runtime with Unexpected false !我得到的最接近的是编译过的东西,但在运行时崩溃了Unexpected false

I'm targetting .NET 4.5, using VS 2015 RC and 1.0.0-rc2 of Roslyn.我的目标是 .NET 4.5,使用 VS 2015 RC 和 Roslyn 的 1.0.0-rc2。

try this one:试试这个:

var doc = @"
/// <summary>
/// Some plain text here.
/// </summary>
";
return SyntaxFactory.Comment(doc);

You can use RoslynQuoter to see how to do this:您可以使用RoslynQuoter来查看如何执行此操作:

        SyntaxFactory.ClassDeclaration(
            @"C")
        .WithKeyword(
            SyntaxFactory.Token(
                SyntaxFactory.TriviaList(
                    SyntaxFactory.Trivia(
                        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(
                                                    new []{
                                                        SyntaxFactory.XmlTextNewLine(
                                                            SyntaxFactory.TriviaList(),
                                                            @"
",
                                                            @"
",
                                                            SyntaxFactory.TriviaList()),
                                                        SyntaxFactory.XmlTextLiteral(
                                                            SyntaxFactory.TriviaList(
                                                                SyntaxFactory.DocumentationCommentExterior(
                                                                    @"///")),
                                                            @" Some plain text here.",
                                                            @" Some plain text here.",
                                                            SyntaxFactory.TriviaList()),
                                                        SyntaxFactory.XmlTextNewLine(
                                                            SyntaxFactory.TriviaList(),
                                                            @"
",
                                                            @"
",
                                                            SyntaxFactory.TriviaList()),
                                                        SyntaxFactory.XmlTextLiteral(
                                                            SyntaxFactory.TriviaList(
                                                                SyntaxFactory.DocumentationCommentExterior(
                                                                    @"///")),
                                                            @" ",
                                                            @" ",
                                                            SyntaxFactory.TriviaList())})))),
                                    SyntaxFactory.XmlText()
                                    .WithTextTokens(
                                        SyntaxFactory.TokenList(
                                            SyntaxFactory.XmlTextNewLine(
                                                SyntaxFactory.TriviaList(),
                                                @"
",
                                                @"
",
                                                SyntaxFactory.TriviaList())))})))),
                SyntaxKind.ClassKeyword,
                SyntaxFactory.TriviaList()))))

Here's what I ended up doing:这是我最终做的:

var tokens = docText.Split('\n')
    .Select(line => XmlTextLiteral(line))
    .ToList();
for(int i = 1; i < tokens.Count; i += 2)
    tokens.Insert(i, XmlTextNewLine("\n"));

var summary = XmlElement("summary",
    SingletonList<XmlNodeSyntax>(XmlText(TokenList(tokens))));
SyntaxTriviaList doc = TriviaList(
    Trivia(DocumentationComment(summary, XmlText("\n"))));
return member.WithLeadingTrivia(doc);

As you noticed, one needs to manually insert XmlTextNewLine for every line separator in summary.正如您所注意到的,总而言之,需要为每个行分隔符手动插入 XmlTextNewLine。 The final XmlText("\\n") is there to ensure member definition actually starts on a new line after /// </summary>最后的XmlText("\\n")是为了确保成员定义实际上在/// </summary>之后的新行上开始

I have not actually tested that in Visual Studio (eg haven't checked tooltips out).我还没有在 Visual Studio 中实际测试过(例如,还没有检查工具提示)。 You might need to generate <p> , <para> , <br/> , or something like that around every newline您可能需要在每个换行符周围生成<p><para><br/>或类似内容

As already noted parsing works and you can build yourself with the necessary XmlText newline.如前所述,解析有效,您可以使用必要的 XmlText 换行符构建自己。

Here is an extension method class that you can base on.这是您可以基于的扩展方法类。 Note that there are classes for the different documentation xml elements.请注意,有不同文档 xml 元素的类。 For instance XmlValueElement and XmlSummaryElement below.例如下面的 XmlValueElement 和 XmlSummaryElement。

public static class XmlComments
{
    private static TMember AddSimple<TMember>(this TMember member,XmlElementSyntax xmlElement) where TMember:MemberDeclarationSyntax
    {
        return member.WithLeadingTrivia(
                TriviaList(
                    Trivia(
                        DocumentationComment(
                            xmlElement,
                            XmlText().WithTextTokens(
                                TokenList(
                                    Token(
                                        TriviaList(),
                                        SyntaxKind.XmlTextLiteralNewLineToken,
                                        Environment.NewLine,
                                        Environment.NewLine,
                                        TriviaList()
                                    )
                                )
                            )
                        )
                    )
                )
            );
    }
    public static PropertyDeclarationSyntax AddValue(this PropertyDeclarationSyntax property,string value)
    {
        return property.AddSimple(
            XmlValueElement(
                XmlText(value)
            ));
    }
    public static TMember AddSummary<TMember>(this TMember member, string value) where TMember: MemberDeclarationSyntax
    {
        return member.AddSimple(
            XmlSummaryElement(
                XmlText(value)
            ));
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM