【问题标题】:Get the SyntaxNode given the linenumber in a SyntaxTree给定 SyntaxTree 中的行号,获取 SyntaxNode
【发布时间】:2017-05-25 04:59:15
【问题描述】:

我想获取给定位置(lineNumber)的行的 SyntaxNode。下面的代码应该是不言自明的,但如果有任何问题,请告诉我。

static void Main()
        {
            string codeSnippet = @"using System;
                                        class Program
                                        {
                                            static void Main(string[] args)
                                            {
                                                Console.WriteLine(""Hello, World!"");
                                            }
                                        }";

            SyntaxTree tree = SyntaxTree.ParseCompilationUnit(codeSnippet);
            string[] lines = codeSnippet.Split('\n');
            SyntaxNode node = GetNode(tree, 6); //How??
        }

        static SyntaxNode GetNode(SyntaxTree tree,int lineNumber)
        {
            throw new NotImplementedException();
            // *** What I did ***
            //Calculted length from using System... to Main(string[] args) and named it (totalSpan)
            //Calculated length of the line(lineNumber) Console.Writeline("Helllo...."); and named it (lineSpan)
            //Created a textspan : TextSpan span = new TextSpan(totalSpan, lineSpan);
            //Was able to get back the text of the line : tree.GetLocation(span);
            //But how to get the SyntaxNode corresponding to that line??
        }

【问题讨论】:

  • 如果该行没有节点怎么办?如果有多个怎么办?
  • @svick 我假设是理想情况。

标签: c# roslyn


【解决方案1】:

首先,要根据行号获取TextSpan,可以使用GetText()返回的SourceTextLines的索引器(但要小心,它从0开始计算行数)。

然后,要获取与该跨度相交的所有节点,您可以使用 DescendantNodes() 的重载。

最后,您过滤该列表以获取完全包含在该行中的第一个节点。

在代码中:

static SyntaxNode GetNode(SyntaxTree tree, int lineNumber)
{
    var lineSpan = tree.GetText().Lines[lineNumber - 1].Span;
    return tree.GetRoot().DescendantNodes(lineSpan)
        .First(n => lineSpan.Contains(n.Span));
}

如果该行上没有节点,则会抛出异常。如果有多个,则返回第一个。

【讨论】:

  • 什么 dll 包含 GetLineFromLineNumber?
  • @johnny5 这个答案很古老,在当前版本的 Roslyn 中没有 GetLineFromLineNumber。我已经更新了适用于我的代码的答案。
  • @svick 你如何提取该行的文本?例如第 2 行的“class Program”?
  • @theanimashaun 你可以使用the overload of SourceText.ToString() that takes a TextSpantree.GetText().ToString(lineSpan)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-06
  • 1970-01-01
  • 1970-01-01
  • 2021-10-29
  • 1970-01-01
相关资源
最近更新 更多