C# Language
.NET Compiler Platform (Roslyn)
Sök…
Skapa arbetsyta från MSBuild-projektet
Hämta först Microsoft.CodeAnalysis.CSharp.Workspaces
nuget innan du fortsätter.
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);
}
För att ladda befintlig kod till arbetsområdet, kompilera och rapportera fel. Därefter kommer koden att finnas i minnet. Härifrån kommer både den syntaktiska och semantiska sidan att vara tillgänglig att arbeta med.
Syntaxträd
Ett syntaxträd är en immutabel datastruktur som representerar programmet som ett träd med namn, kommandon och markeringar (som tidigare konfigurerats i redigeraren.)
Antag till exempel att en Microsoft.CodeAnalysis.Compilation
instans med namnet compilation
har konfigurerats. Det finns flera sätt att lista namnen på varje variabel som deklareras i den laddade koden. För att göra det naivt, ta alla syntaxbitar i varje dokument ( DescendantNodes
metoden) och använd Linq för att välja noder som beskriver variabeldeklaration:
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);
}
}
Varje typ av C # -konstruktion med motsvarande typ kommer att finnas i syntaxträdet. För att snabbt hitta specifika typer använder du Syntax Visualizer
fönstret från Visual Studio. Detta kommer att tolka det nuvarande öppnade dokumentet som ett Roslyn-syntaxträd.
Semantisk modell
En semantisk modell erbjuder en djupare nivå av tolkning och insikt i kod jämför med ett syntaxträd. Där syntaxträd kan berätta variabler, ger semantiska modeller också typen och alla referenser. Syntaxträd märker metodsamtal, men semantiska modeller hänvisar till den exakta platsen som metoden deklareras (efter överbelastningsupplösning har tillämpats.)
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)"
}
}
}
}
Detta visar en lista över lokala variabler med ett syntaxträd. Sedan konsulterar den semantiska modellen för att få fullständigt namn och hitta alla referenser för varje variabel.