roslynAlbero della sintassi

introduzione

Una delle parti principali del compilatore di Roslyn è l'API Syntax. Espone gli alberi di sintassi utilizzati dai compilatori per comprendere i programmi Visual Basic e C #.

Osservazioni

  • Syntax Tree è un Parse Tree nel contesto del compilatore di Roslyn.

Ottenere il Syntax Tree Root da un documento.

Se hai già accesso alla tua classe Document dal tuo spazio di lavoro ( Usando Aree di lavoro ) è facile accedere alla radice dell'albero Syntax.

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

 var syntaxRoot = await document.GetSyntaxRootAsync();

Attraversamento dell'albero della sintassi Utilizzando LINQ

Puoi facilmente navigare in un albero della sintassi usando LINQ. Ad esempio è facile ottenere tutti i nodi ClassDeclarationSyntax (classi dichiarate), che hanno un nome che inizia con la lettera A :

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

O ottenendo tutte le classi che hanno attributi:

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

Attraversamento dell'albero della sintassi mediante CSharpSyntaxWalker

La classe CSharpSyntaxWalker è fuori dall'implementazione del pattern Visitor, che possiamo usare per attraversare il nostro Syntax Tree. Ecco un semplice esempio di Syntax Walker che raccoglie tutte le struct -s che hanno un nome, iniziando con la lettera 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);
        }
    }
}

Possiamo usare il nostro SyntaxWalker nel modo seguente:

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