如何在 Roslyn 中向 ClassDeclarationSyntax 添加 XML 文档注释?
How do I add an XML Doc Comment to a ClassDeclarationSyntax in Roslyn?
我有一些代码可以构建 class:
return SyntaxFactory
.ClassDeclaration(name)
.AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword))
.WithMembers(GetProperties());
一切正常,并输出我期望的 class。我想为此添加一个 XML 文档:
/// <summary>
/// Some plain text here.
/// </summary>
我不需要任何花哨的东西,只需要纯文本。我正在努力寻找这方面的任何例子,并且经历了 Annotations
、Trivia
的各种重载,以及挂起 SyntaxFactory
(XmlComment
、XmlElementStartTag
、DocumentationCommentExterior
、DocumentationCommentTrivia
) 没有喜悦(具有讽刺意味的是,其中 none 有 XML 评论!)。我得到的最接近的是编译的东西,但在运行时崩溃 Unexpected false
!
我的目标是 .NET 4.5,使用 VS 2015 RC 和 Roslyn 的 1.0.0-rc2。
您可以使用 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()))))
试试这个:
var doc = @"
/// <summary>
/// Some plain text here.
/// </summary>
";
return SyntaxFactory.Comment(doc);
这是我最后做的事情:
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);
如您所见,需要为摘要中的每个行分隔符手动插入 XmlTextNewLine。
最后的 XmlText("\n")
是为了确保成员定义实际上在 /// </summary>
之后的新行开始
我还没有在 Visual Studio 中实际测试过(例如,还没有检查工具提示)。您可能需要在每个换行符周围生成 <p>
、<para>
、<br/>
或类似内容
如前所述,解析有效,您可以使用必要的 XmlText 换行符构建自己。
这是您可以基于的扩展方法class。请注意,不同的文档 xml 元素有 classes。例如下面的 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)
));
}
}
我有一些代码可以构建 class:
return SyntaxFactory
.ClassDeclaration(name)
.AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword))
.WithMembers(GetProperties());
一切正常,并输出我期望的 class。我想为此添加一个 XML 文档:
/// <summary>
/// Some plain text here.
/// </summary>
我不需要任何花哨的东西,只需要纯文本。我正在努力寻找这方面的任何例子,并且经历了 Annotations
、Trivia
的各种重载,以及挂起 SyntaxFactory
(XmlComment
、XmlElementStartTag
、DocumentationCommentExterior
、DocumentationCommentTrivia
) 没有喜悦(具有讽刺意味的是,其中 none 有 XML 评论!)。我得到的最接近的是编译的东西,但在运行时崩溃 Unexpected false
!
我的目标是 .NET 4.5,使用 VS 2015 RC 和 Roslyn 的 1.0.0-rc2。
您可以使用 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()))))
试试这个:
var doc = @"
/// <summary>
/// Some plain text here.
/// </summary>
";
return SyntaxFactory.Comment(doc);
这是我最后做的事情:
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);
如您所见,需要为摘要中的每个行分隔符手动插入 XmlTextNewLine。
最后的 XmlText("\n")
是为了确保成员定义实际上在 /// </summary>
我还没有在 Visual Studio 中实际测试过(例如,还没有检查工具提示)。您可能需要在每个换行符周围生成 <p>
、<para>
、<br/>
或类似内容
如前所述,解析有效,您可以使用必要的 XmlText 换行符构建自己。
这是您可以基于的扩展方法class。请注意,不同的文档 xml 元素有 classes。例如下面的 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)
));
}
}