C# Language
.NET Compiler Platform (Roslyn)
Zoeken…
Creëer werkruimte van MSBuild project
Download eerst het nuget Microsoft.CodeAnalysis.CSharp.Workspaces
voordat u doorgaat.
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);
}
Compileer en rapporteer fouten om bestaande code in de werkruimte te laden. Daarna wordt de code in het geheugen opgeslagen. Vanaf hier zullen zowel de syntactische als semantische kant beschikbaar zijn om mee te werken.
Syntaxisboom
Een syntaxisstructuur is een onveranderlijke gegevensstructuur die het programma weergeeft als een structuur met namen, opdrachten en tekens (zoals eerder geconfigureerd in de editor).
Neem bijvoorbeeld aan dat een instantie Microsoft.CodeAnalysis.Compilation
naam compilation
is geconfigureerd. Er zijn meerdere manieren om de namen weer te geven van elke variabele die in de geladen code is opgegeven. Om dit naïef te doen, neemt u alle stukjes syntaxis in elk document (de DescendantNodes
methode) en gebruikt u Linq om knooppunten te selecteren die de variabele declaratie beschrijven:
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);
}
}
Elk type C # -construct met een overeenkomstig type bestaat in de syntaxisstructuur. Gebruik het Syntax Visualizer
venster van Visual Studio om snel specifieke typen te vinden. Hiermee wordt het huidige geopende document geïnterpreteerd als een syntaxisstructuur van Roslyn.
Semantisch model
Een semantisch model biedt een dieper niveau van interpretatie en inzicht in codevergelijking met een syntaxisboom. Waar syntaxisbomen de namen van variabelen kunnen vertellen, geven semantische modellen ook het type en alle referenties. Syntaxisbomen merken methodeaanroepen op, maar semantische modellen verwijzen naar de exacte locatie waar de methode wordt gedeclareerd (nadat de overbelastingsresolutie is toegepast.)
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)"
}
}
}
}
Hiermee wordt een lijst met lokale variabelen uitgevoerd met behulp van een syntaxisboom. Vervolgens raadpleegt het het semantische model om de volledige typenaam te krijgen en alle referenties van elke variabele te vinden.