Suche…


Erstellen Sie einen Arbeitsbereich aus dem MSBuild-Projekt

Besorgen Sie sich zunächst das Microsoft.CodeAnalysis.CSharp.Workspaces Nuget, bevor Sie fortfahren.

var workspace = Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace.Create();
var project = await workspace.OpenProjectAsync(projectFilePath);
var compilation = await project.GetCompilationAsync();

foreach (var diagnostic in compilation.GetDiagnostics()
    .Where(d => d.Severity == Microsoft.CodeAnalysis.DiagnosticSeverity.Error))
{
    Console.WriteLine(diagnostic);
}

Um vorhandenen Code in den Arbeitsbereich zu laden, kompilieren und melden Sie Fehler. Danach wird der Code im Speicher abgelegt. Von hier aus kann sowohl mit der syntaktischen als auch mit der semantischen Seite gearbeitet werden.

Syntaxbaum

Ein Syntaxbaum ist eine unveränderliche Datenstruktur, die das Programm als einen Baum mit Namen, Befehlen und Marken darstellt (wie zuvor im Editor konfiguriert).

Angenommen, eine Microsoft.CodeAnalysis.Compilation Instanz namens compilation wurde konfiguriert. Es gibt mehrere Möglichkeiten, die Namen aller im geladenen Code deklarierten Variablen aufzulisten. Um dies einfach zu tun, nehmen Sie alle Syntaxteile in jedem Dokument ( DescendantNodes Methode) und verwenden Sie Linq, um Knoten auszuwählen, die die Deklaration von Variablen beschreiben:

foreach (var syntaxTree in compilation.SyntaxTrees)
{
    var root = await syntaxTree.GetRootAsync();
    var declaredIdentifiers = root.DescendantNodes()
        .Where(an => an is VariableDeclaratorSyntax)
        .Cast<VariableDeclaratorSyntax>()
        .Select(vd => vd.Identifier);

    foreach (var di in declaredIdentifiers)
    {
        Console.WriteLine(di);
    }
}

Jeder Typ eines C # -Konstrukts mit einem entsprechenden Typ ist im Syntaxbaum vorhanden. Um bestimmte Typen schnell zu finden, verwenden Sie das Syntax Visualizer Fenster in Visual Studio. Dadurch wird das aktuell geöffnete Dokument als Roslyn-Syntaxbaum interpretiert.

Semantisches Modell

Ein semantisches Modell bietet eine tiefere Interpretationsebene und Einblick in den Code-Vergleich mit einem Syntaxbaum. Wo Syntaxbäume die Namen von Variablen angeben können, geben Semantikmodelle auch den Typ und alle Referenzen an. Syntaxbäume beachten Methodenaufrufe, aber semantische Modelle geben Hinweise auf den genauen Ort, an dem die Methode deklariert wird (nachdem die Überlastauflösung angewendet wurde)

var workspace = Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace.Create();
var sln = await workspace.OpenSolutionAsync(solutionFilePath);
var project = sln.Projects.First();
var compilation = await project.GetCompilationAsync();

foreach (var syntaxTree in compilation.SyntaxTrees)
{
    var root = await syntaxTree.GetRootAsync();

    var declaredIdentifiers = root.DescendantNodes()
        .Where(an => an is VariableDeclaratorSyntax)
        .Cast<VariableDeclaratorSyntax>();

    foreach (var di in declaredIdentifiers)
    {
        Console.WriteLine(di.Identifier);
        // => "root"

        var variableSymbol = compilation
            .GetSemanticModel(syntaxTree)
            .GetDeclaredSymbol(di) as ILocalSymbol;

        Console.WriteLine(variableSymbol.Type);
        // => "Microsoft.CodeAnalysis.SyntaxNode"

        var references = await SymbolFinder.FindReferencesAsync(variableSymbol, sln);
        foreach (var reference in references)
        {
            foreach (var loc in reference.Locations)
            {
                Console.WriteLine(loc.Location.SourceSpan);
                // => "[1375..1379)"
            }
        }
    }
}

Dadurch wird eine Liste lokaler Variablen mit einem Syntaxbaum ausgegeben. Dann konsultiert es das semantische Modell, um den vollständigen Typnamen zu erhalten und alle Referenzen zu jeder Variablen zu finden.



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow