Как правильно использовать ControlFlowGraph из анализа кода Розлина в C# - PullRequest
0 голосов
/ 13 февраля 2020

Я не могу понять, почему я получаю сообщение об ошибке (с использованием VS2017) для приведенного ниже кода, связанного с отсутствием класса ControlFlowGraph, который должен быть частью пакета Microsoft.CodeAnalysis.FlowAnalysis:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Build.Locator;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.MSBuild;
using Microsoft.CodeAnalysis.FlowAnalysis;

namespace CodeAnalysisApp3
{
    class Program
    {
        static async Task Main(string[] args)
        {
            // Attempt to set the version of MSBuild.
            var visualStudioInstances = MSBuildLocator.QueryVisualStudioInstances().ToArray();
            var instance = visualStudioInstances[0];

            Console.WriteLine($"Using MSBuild at '{instance.MSBuildPath}' to load projects.");

            // NOTE: Be sure to register an instance with the MSBuildLocator 
            //       before calling MSBuildWorkspace.Create()
            //       otherwise, MSBuildWorkspace won't MEF compose.
            MSBuildLocator.RegisterInstance(instance);

            using (var workspace = MSBuildWorkspace.Create())
            {
                // Print message for WorkspaceFailed event to help diagnosing project load failures.
                workspace.WorkspaceFailed += (o, e) => Console.WriteLine(e.Diagnostic.Message);

                var solutionPath = args[0];
                Console.WriteLine($"Loading solution '{solutionPath}'");

                // Attach progress reporter so we print projects as they are loaded.
                var solution = await workspace.OpenSolutionAsync(solutionPath, new ConsoleProgressReporter());
                Console.WriteLine($"Finished loading solution '{solutionPath}'");

                // TODO: Do analysis on the projects in the loaded solution
                CSharpParseOptions options = CSharpParseOptions.Default
                .WithFeatures(new[] { new KeyValuePair<string, string>("flow-analysis", "") });

                var projIds = solution.ProjectIds;

                var project = solution.GetProject(projIds[0]);

                Compilation compilation = await project.GetCompilationAsync();

                if (compilation != null && !string.IsNullOrEmpty(compilation.AssemblyName))
                {
                    var mySyntaxTree = compilation.SyntaxTrees.First();

                    // get syntax nodes for methods
                    var methodNodes = from methodDeclaration in mySyntaxTree.GetRoot().DescendantNodes()
                               .Where(x => x is MethodDeclarationSyntax)
                                      select methodDeclaration;

                    foreach (MethodDeclarationSyntax node in methodNodes)
                    {
                        var model = compilation.GetSemanticModel(node.SyntaxTree);
                        node.Identifier.ToString();
                        if (node.SyntaxTree.Options.Features.Any())
                        {
                            var graph = ControlFlowGraph.Create(node, model); // CFG is here
                        }
                    }
                }
            }
        }

        private class ConsoleProgressReporter : IProgress<ProjectLoadProgress>
        {
            public void Report(ProjectLoadProgress loadProgress)
            {
                var projectDisplay = Path.GetFileName(loadProgress.FilePath);
                if (loadProgress.TargetFramework != null)
                {
                    projectDisplay += $" ({loadProgress.TargetFramework})";
                }

                Console.WriteLine($"{loadProgress.Operation,-15} {loadProgress.ElapsedTime,-15:m\\:ss\\.fffffff} {projectDisplay}");
            }
        }
    }
}

Однако, когда я компилирую вышеуказанный код, я получаю следующее сообщение об ошибке с VS2017:

1>Program.cs(67,41,67,57): error CS0103: The name 'ControlFlowGraph' does not exist in the current context
1>Done building project "CodeAnalysisApp3.csproj" -- FAILED.
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========

Используемая версия:

Microsoft (R) Visual C# Compiler version 4.8.3761.0
for C# 5

Ответы [ 2 ]

0 голосов
/ 14 февраля 2020

Я смог решить проблему, когда использовал пакеты roslyn CodeAnalysis с правильными версиями:

CodeAnalysis.CSharp.Workspaces (3.4.0)
CodeAnalysis.FlowAnalysis.Utilities (2.9.6)
CodeAnalysis.Workspaces.MSBuild (3.4.0)

Целевой фреймворк: .NETFramework 4.7.2

Создана ссылка на закрытую проблему для этого вопроса на Rslyn Github репо здесь

0 голосов
/ 14 февраля 2020

На основании своего теста я могу использовать класс ControlFlowGraph.

Я установил следующий пакет nuget.

Microsoft.CodeAnalysis

Microsoft.Build.Locator

Затем вы увидите следующий результат.

enter image description here

Кроме того, я использовал. net framwork 4.6.1.

...