Roslyn - 获得分组单行评论

时间:2018-04-15 15:54:36

标签: c# comments roslyn

我正在用C#编写程序,用于从代码中提取注释。我正在使用Roslyn编译器来做到这一点。这很棒,因为我只是访问整个抽象语法树并从解决方案中的文件中获取SingleLineComment trivia,MultiLineComment trivia和DocumentationComment trivia语法。但是有一个问题,因为程序员经常写这样的评论:

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.

您可以看到这些是三行单行注释,但我希望它们可以作为一条注释从代码中获取。我能用Roslyn实现这个目标吗?或者还有其他办法吗?因为当程序员使用单行注释语法编写多行通知时,这是常见的情况。

我提取评论的代码如下所示:

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using System.Collections.Generic;

namespace RoslynPlay
{
    public class CommentStore
    {
        public List<Comment> Comments { get; } = new List<Comment>();

        public void AddCommentTrivia(SyntaxTrivia trivia,
            LocationStore commentLocationstore, string fileName)
        {
            if (trivia.Kind() == SyntaxKind.SingleLineCommentTrivia)
            {
                Comments.Add(new SingleLineComment(trivia.ToString(),
                    trivia.GetLocation().GetLineSpan().EndLinePosition.Line + 1, commentLocationstore)
                {
                    FileName = fileName,
                });
            }
            else if (trivia.Kind() == SyntaxKind.MultiLineCommentTrivia)
            {
                Comments.Add(new MultiLineComment(trivia.ToString(),
                    trivia.GetLocation().GetLineSpan().StartLinePosition.Line + 1,
                    trivia.GetLocation().GetLineSpan().EndLinePosition.Line + 1, commentLocationstore)
                {
                    FileName = fileName,
                });
            }
        }

        public void AddCommentNode(DocumentationCommentTriviaSyntax node,
            LocationStore commentLocationstore, string fileName)
        {
            Comments.Add(new DocComment(node.ToString(),
                node.GetLocation().GetLineSpan().StartLinePosition.Line + 1,
                node.GetLocation().GetLineSpan().EndLinePosition.Line,
                commentLocationstore)
            {
                FileName = fileName,
            });
        }
    }
}

并在主主文件(Program.cs)中我从这样的代码中启动注释提取:

    string fileContent;
    SyntaxTree tree;
    SyntaxNode root;
    CommentsWalker commentWalker;
    MethodsAndClassesWalker methodWalker;
    string[] files = Directory.GetFiles(projectPath, $"*.cs", SearchOption.AllDirectories);
    var commentStore = new CommentStore();

    Console.WriteLine("Reading files...");
    ProgressBar progressBar = new ProgressBar(files.Length);

    foreach (var file in files)
    {
        fileContent = File.ReadAllText(file);
        string filePath = new Regex($@"{projectPath}\\(.*)$").Match(file).Groups[1].ToString();
        tree = CSharpSyntaxTree.ParseText(fileContent);
        root = tree.GetRoot();
        commentWalker = new CommentsWalker(filePath, commentStore);
        commentWalker.Visit(root);

        progressBar.UpdateAndDisplay();
    }

这里也是评论沃克:

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;

namespace RoslynPlay
{
    public class CommentsWalker : CSharpSyntaxWalker
    {
        private string _fileName;
        private CommentStore _commentStore;

        public CommentsWalker(string fileName,
            CommentStore commentStore)
            : base(SyntaxWalkerDepth.StructuredTrivia)
        {
            _fileName = fileName;
            _commentStore = commentStore;
        }

        public override void VisitTrivia(SyntaxTrivia trivia)
        {
            if (trivia.Kind() == SyntaxKind.SingleLineCommentTrivia
                || trivia.Kind() == SyntaxKind.MultiLineCommentTrivia)
            {
                _commentStore.AddCommentTrivia(trivia, _commentLocationStore, _fileName);
            }
            base.VisitTrivia(trivia);
        }

        public override void VisitDocumentationCommentTrivia(DocumentationCommentTriviaSyntax node)
        {
            _commentStore.AddCommentNode(node, _commentLocationStore, _fileName);
            base.VisitDocumentationCommentTrivia(node);
        }
    }
}

问题是因为trivia.Kind()== SyntaxKind.SingleLineCommentTrivia只提取单行注释,但我想将单行注释块提取为一条注释。

0 个答案:

没有答案