Page 77 - CSharp/C#
P. 77
A Semantic Model offers a deeper level of interpretation and insight of code compare to a syntax
tree. Where syntax trees can tell the names of variables, semantic models also give the type and
all references. Syntax trees notice method calls, but semantic models give references to the
precise location the method is declared (after overload resolution has been applied.)
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)"
}
}
}
}
This outputs a list of local variables using a syntax tree. Then it consults the semantic model to get
the full type name and find all references of every variable.
Read .NET Compiler Platform (Roslyn) online: https://riptutorial.com/csharp/topic/4886/-net-
compiler-platform--roslyn-
https://riptutorial.com/ 23

