2012-12-14 10 views
14

Chcę uzyskać węzeł składniowy wiersza z podaniem położenia (numer wiersza). Poniższy kod powinien być oczywisty, ale daj mi znać na wszelkie pytania.Pobierz węzeł składni podając tekst wierszy w 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

Co jeśli w tym wierszu nie ma węzła? Co jeśli jest więcej niż jeden? – svick

+0

@svick Zakładam idealny przypadek. –

Odpowiedz

10

Po pierwsze, aby uzyskać TextSpan na podstawie numeru linii, można użyć podziałowe z Lines z SourceText zwróconej przez GetText() (ale uważaj, liczy linie od 0).

Następnie, aby uzyskać wszystkie węzły, które przecinają ten zakres, można użyć przeciążenia z DescendantNodes().

Na koniec filtrujesz tę listę, aby uzyskać pierwszy węzeł, który jest w pełni zawarty w tym wierszu.

W kodzie:

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)); 
} 

Jeśli węzeł nie ma na tej linii, to wyjątek. Jeśli jest więcej niż jeden, zwróci pierwszą.

+0

Co dll zawiera GetLineFromLineNumber? –

+1

@ johnny5 Ta odpowiedź jest starożytna, nie ma "GetLineFromLineNumber" w aktualnej wersji Roslyn. Zaktualizowałem odpowiedź na kod, który działa teraz dla mnie. – svick

Powiązane problemy