如何使用Roslyn读取XML文档注释

27

我希望能够使用Roslyn解析C#源代码的同时阅读XML文档注释。

/// <summary>
/// Documentation...
/// </summary>

我尝试在ParseOptions中设置ParseDocumentationComments,但似乎没有任何效果?

var parseOptions = ParseOptions.Default.WithParseDocumentationComments(true);
SyntaxTree unit = SyntaxTree.ParseFile(file, parseOptions);

1
你是如何尝试精确读取XML注释的? - user7116
3个回答

35

你需要进行以下操作之一:

  1. 查看包含XML文档注释的语法的 LeadingTrivia
  2. 构建一个 Compilation,找到具有XML文档注释的 Symbol 并使用其上的 GetDocumentationComment() 方法。

完整示例:

using Roslyn.Compilers.CSharp;
using System;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        var tree = SyntaxTree.ParseText(@"
/// <summary>This is an xml doc comment</summary>
class C
{
}");
        var classNode = (ClassDeclarationSyntax)tree.GetRoot().Members.First();
        var trivia = classNode.GetLeadingTrivia().Single(t => t.Kind == SyntaxKind.DocumentationCommentTrivia);
        var xml = trivia.GetStructure();
        Console.WriteLine(xml);

        var compilation = Compilation.Create("test", syntaxTrees: new[] { tree });
        var classSymbol = compilation.GlobalNamespace.GetTypeMembers("C").Single();
        var docComment = classSymbol.GetDocumentationComment();
        Console.WriteLine(docComment.SummaryTextOpt);
    }
}

OP提供了一个多行注释的示例。我也有同样的问题。您能否重新编写您的代码以演示如何读取多行文档注释(根据原始问题)? - Quark Soup
对于 Symbol 的情况,它应该是相同的。对于语法的情况,您只需查看 MultiLineDocumentationCommentTrivia - Kevin Pilch
我认为 GetDocumentationComment 已经被替换为 GetDocumentationCommentXml. - Jack Ukleja

7

仅仅是更新一下Kevin Pilch的答案:

  1. Add Microsoft.CodeAnalysis.CSharp via nuget

  2. Code will be as follows:

    using System;
    using System.Linq;
    using Microsoft.CodeAnalysis.CSharp;
    using Microsoft.CodeAnalysis.CSharp.Syntax;
    
    class Program
    {
        static void Main(string[] args)
        {
            var tree = CSharpSyntaxTree.ParseText(@"
    /// <summary> This is an xml doc comment </summary>
    class C
    {
    }");
            var root = (CompilationUnitSyntax) tree.GetRoot();
            var classNode = (ClassDeclarationSyntax) (root.Members.First());
    
            var trivias = classNode.GetLeadingTrivia();
            var xmlCommentTrivia = trivias.FirstOrDefault(t => t.Kind() == SyntaxKind.SingleLineDocumentationCommentTrivia);
            var xml = xmlCommentTrivia.GetStructure();
            Console.WriteLine(xml);
    
            var compilation = CSharpCompilation.Create("test", syntaxTrees: new[] {tree});
            var classSymbol = compilation.GlobalNamespace.GetTypeMembers("C").Single();
            var docComment = classSymbol.GetDocumentationCommentXml();
            Console.WriteLine(docComment);
        }
    }
    

添加 "Microsoft.CodeAnalysis.CSharp" 非常重要。否则 t.Kind() 方法将无法正常工作! - Utsav Chokshi

2

更新:

FirstOrDefault 方法已不再可用。因此,请使用 enumerator 代替。

更新后的代码:

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

class Program
{
    static void Main(string[] args)
    {
        var tree = CSharpSyntaxTree.ParseText(@"
/// <summary> This is an xml doc comment </summary>
class C
{
}");
        var root = (CompilationUnitSyntax) tree.GetRoot();
        var classNode = (ClassDeclarationSyntax) (root.Members.First());

        var trivias = classNode.GetLeadingTrivia();
        var enumerator = trivias.GetEnumerator();
        while (enumerator.MoveNext())
        {
           var trivia = enumerator.Current;
           if(trivia.Kind().Equals(SyntaxKind.SingleLineDocumentationCommentTrivia))
           {
               var xml = trivia.GetStructure();
               Console.WriteLine(xml);
           }
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接