I can't find a way to construct a control flow graph for c# code using Roslyn.
I know there is a namespace in the Roslyn compiler called "Microsoft.CodeAnalysis.FlowAnalysis" that contains some classes to create a control flow graph but I don't know how to use it.
https://learn.microsoft.com/en-us/dotnet/api/microsoft.codeanalysis.flowanalysis?view=roslyn-dotnet
there is a class called ControlFlowGraph.cs but the problem i can't create an object or a subclass from this class. https://learn.microsoft.com/en-us/dotnet/api/microsoft.codeanalysis.flowanalysis.controlflowgraph?view=roslyn-dotnet
please if anyone knows how to use this namespace to construct a control flow graph or if there is an example to use. thank you
I have manage to create the CFG from a method node:
CSharpParseOptions options = CSharpParseOptions.Default
.WithFeatures(new[] { new KeyValuePair<string, string>("flow-analysis", "")
});
MSBuildWorkspace workspace = MSBuildWorkspace.Create();
Solution solution = workspace.OpenSolutionAsync(solutionUrl).Result; // path to your SLN file
ProjectDependencyGraph projectGraph = solution.GetProjectDependencyGraph();
Dictionary<string, Stream> assemblies = new Dictionary<string, Stream>();
var projects = projectGraph.GetTopologicallySortedProjects().ToDictionary(
p => p,
p => solution.GetProject(p).Name);
var bllProjectId = projects.First(p => p.Value == "<your project name>").Key; // choose project for analysis
var projectId = bllProjectId;
solution = solution.WithProjectParseOptions(projectId, options);
Compilation compilation = solution.GetProject(projectId).GetCompilationAsync().Result;
if (compilation != null && !string.IsNullOrEmpty(compilation.AssemblyName))
{
var syntaxTree = compilation.SyntaxTrees.First();
// get syntax nodes for methods
var methodNodes = from methodDeclaration in syntaxTree.GetRoot().DescendantNodes()
.Where(x => x is MethodDeclarationSyntax)
select methodDeclaration;
foreach (MethodDeclarationSyntax node in methodNodes)
{
var model = compilation.GetSemanticModel(node.SyntaxTree);
node.Identifier.ToString().Dump();
if (node.SyntaxTree.Options.Features.Any())
{
var graph = ControlFlowGraph.Create(node, model); // CFG is here
}
else
{
// "No features".Dump();
}
}
}
The next step will be anaylysis of the CFG ...
Karel