Получите SyntaxNode, учитывая номер строки в SyntaxTree
Я хочу получить SyntaxNode строки с указанием местоположения (lineNumber). Код ниже должен быть понятным, но дайте мне знать о любых вопросах.
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??
}
Ответы
Ответ 1
Во-первых, чтобы получить TextSpan
на основе номера строки, вы можете использовать индекс Lines
SourceText
, возвращаемый GetText()
(но осторожно, он подсчитывает строки из 0).
Затем, чтобы получить все узлы, которые пересекают этот диапазон, вы можете использовать перегрузку DescendantNodes()
.
Наконец, вы фильтруете этот список, чтобы получить первый node, который содержится полностью в этой строке.
В коде:
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));
}
Если в этой строке нет node, это вызовет исключение. Если их больше одного, он вернет первый.