ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

c# – 将令牌和琐事映射到行号

2019-06-23 21:56:01  阅读:208  来源: 互联网

标签:c roslyn


我正在尝试使用Roslyn将令牌和琐事映射到行号.

以下是@Kevin Pilch-Bisson帮助下的最新尝试.

public class CSharpSlocAnalyser : ISlocAnalyser
{
    public long GetSlocFor(IEnumerable<FileInfo> files, SlocOptions options)
    {
        var tree = CSharpSyntaxTree.ParseText(
@"using /* Blah */
    System;
// Blah
public class MyClass
{
    public void MyMethod()
    {
        var blah = ""abc"";
    }
}");

        var root = tree.GetRoot();
        var walker = new CustomWalker();
        walker.Visit(root);
        var lineMap = walker.LineMap;

        return 1;
    }

    public class CustomWalker : CSharpSyntaxWalker
    {
        public Dictionary<int, List<object>> LineMap { get; }

        public CustomWalker() : base(SyntaxWalkerDepth.StructuredTrivia)
        {
            LineMap = new Dictionary<int, List<object>>();
        }

        public override void VisitToken(SyntaxToken token)
        {
            var parent = token.Parent;
            while (parent.GetText().Length < token.Span.Start)
            {
                parent = parent.Parent;
            }

            var text = parent.GetText();
            var line = text.Lines.GetLineFromPosition(token.Span.Start).LineNumber;

            if (!LineMap.ContainsKey(line))
            {
                LineMap.Add(line, new List<object>());
            }

            LineMap[line].Add(token);

            base.VisitToken(token);
        }

        public override void VisitTrivia(SyntaxTrivia trivia)
        {
            var parent = trivia.Token.Parent;
            while (parent.GetText().Length < trivia.Span.Start)
            {
                parent = parent.Parent;
            }

            var text = parent.GetText();
            var line = text.Lines.GetLineFromPosition(trivia.Span.Start).LineNumber;

            if (!LineMap.ContainsKey(line))
            {
                LineMap.Add(line, new List<object>());
            }

            LineMap[line].Add(trivia);

            base.VisitTrivia(trivia);
        }
    }
}

但是这会生成以下映射:

Line 0
    UsingKeyword - 'using'
    WhitespaceTrivia - ' '
    MultiLineCommentTrivia - '/* Blah */'
    EndOfLineTrivia - '
'
Line 1
    IdentifierToken - 'System'
    WhitespaceTrivia - '    '
    SemicolonToken - ';'
    EndOfLineTrivia - '
'
Line 2
    SingleLineCommentTrivia - '// Blah'
Line 3
    PublicKeyword - 'public'
    EndOfLineTrivia - '
'
    WhitespaceTrivia - ' '
    ClassKeyword - 'class'
    WhitespaceTrivia - ' '
    IdentifierToken - 'MyClass'
    EndOfLineTrivia - '
'
    WhitespaceTrivia - '    '
Line 4
    OpenBraceToken - '{'
    EndOfLineTrivia - '
'
    PublicKeyword - 'public'
Line 5
    WhitespaceTrivia - ' '
    VoidKeyword - 'void'
    WhitespaceTrivia - ' '
    IdentifierToken - 'MyMethod'
    OpenParenToken - '('
    CloseParenToken - ')'
    EndOfLineTrivia - '
'
    WhitespaceTrivia - '    '
Line 6
    OpenBraceToken - '{'
    EndOfLineTrivia - '
'
    WhitespaceTrivia - '        '
Line 7
    IdentifierToken - 'var'
    WhitespaceTrivia - ' '
    IdentifierToken - 'blah'
    WhitespaceTrivia - ' '
    EqualsToken - '='
    WhitespaceTrivia - ' '
    StringLiteralToken - '"abc"'
    SemicolonToken - ';'
    EndOfLineTrivia - '
'
Line 8
    CloseBraceToken - '}'
    WhitespaceTrivia - '    '
    EndOfLineTrivia - '
'
Line 9
    CloseBraceToken - '}'
    EndOfFileToken - ''

一直看起来很好,直到第2行,它不包含和行尾琐事,第3行包含2行尾琐事,一切似乎从那里走出轨道.

我究竟做错了什么?我只想将令牌和琐事映射到原始源代码行.

解决方法:

SourceText已经跟踪以Lines属性结尾的行.您可以使用类似GetLineAndOffset中的代码

标签:c,roslyn
来源: https://codeday.me/bug/20190623/1274712.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有