roslyn語法樹

介紹

Roslyn編譯器的一個主要部分是Syntax API。它公開了編譯器用來理解Visual Basic和C#程序的語法樹。

備註

  • 語法樹是Roslyn編譯器上下文中的解析樹

從文檔中獲取語法樹根。

如果您已經可以從工作區( 使用工作區 )訪問Document類,則可以輕鬆訪問語法樹的根目錄。

 Document document = ... // Get document from workspace or other source 

 var syntaxRoot = await document.GetSyntaxRootAsync();

使用LINQ遍歷語法樹

您可以使用LINQ輕鬆導航語法樹。例如,很容易獲得所有ClassDeclarationSyntax節點(聲明的類),其名稱以字母A開頭:

var allClassesWithNameStartingWithA = syntaxRoot.DescendantNodes()
    .OfType<ClassDeclarationSyntax>()
    .Where(x => x.Identifier.ToString().StartsWith("A"));

或者獲取所有具有屬性的類:

var allClassesWithAttriutes = syntaxRoot.DescendantNodes()
    .OfType<ClassDeclarationSyntax>()
    .Where(x => x.AttributeLists.Any(y => y.Attributes.Any()));

使用CSharpSyntaxWalker遍歷語法樹

CSharpSyntaxWalker類是Visitor模式的開箱即用實現,我們可以使用它來遍歷我們的語法樹。下面是一個簡單的Syntax Walker示例,它收集所有具有名稱的struct以字母A開頭:

public class StructCollector : CSharpSyntaxWalker
{
    public StructCollector()
    {
        this.Structs = new List<StructDeclarationSyntax>();
    }

    public IList<StructDeclarationSyntax> Structs { get; }

    public override void VisitStructDeclaration(StructDeclarationSyntax node)
    {
        if (node.Identifier.ToString().StartsWith("A"))
        {
            this.Structs.Add(node);
        }
    }
}

我們可以通過以下方式使用SyntaxWalker:

var structCollector = new StructCollector();
structCollector.Visit(syntaxRoot); // Or any other syntax node
Console.WriteLine($"The number of structs that have a name starting with the letter 'A' is {structCollector.Structs.Count}");