roslyn構文ツリー

前書き

Roslynコンパイラの主要部分の1つは、Syntax APIです。これは、コンパイラがVisual BasicおよびC#プログラムを理解するために使用する構文ツリーを公開します。

備考

  • 構文木は、Roslynコンパイラの文脈における解析木です。

ドキュメントからシンタクスツリールートを取得する。

ワークスペースからDocumentクラスへのアクセスが既にある場合(ワークスペースの使用 )、構文ツリーのルートに簡単にアクセスできます。

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

 var syntaxRoot = await document.GetSyntaxRootAsync();

LINQを使用した構文木のトラバース

LINQを使用して構文木を簡単にナビゲートすることができます。たとえば、文字A始まる名前を持つすべてのClassDeclarationSyntaxノード(宣言されたクラス)を簡単に取得できます。

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パターンのボックス実装であり、構文木をトラバースするために使用できます。以下は、 Aという文字で始まる名前を持つすべてのstructを収集するSyntax Walkerの簡単な例です:

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