2012-12-14 42 views
14

我想獲得給定位置(lineNumber)的線的語法結點。下面的代碼應該是不言自明的,但讓我知道任何問題。在SyntaxTree中給定語法結點的語法節點

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?? 
     } 
+0

如果該行沒有節點會怎麼樣?如果有多個呢? – svick

+0

@svick我假設理想情況。 –

回答

10

第一,得到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)); 
} 

如果在該行沒有節點,這將引發異常。如果有多個,它會返回第一個。

+0

什麼dll包含GetLineFromLineNumber? –

+1

@ johnny5這個答案很古老,在當前版本的Roslyn中沒有'GetLineFromLineNumber'。我已經更新了現在適用於我的代碼的答案。 – svick