【问题标题】:How to properly use ControlFlowGraph from roslyn code analysis in C#如何在 C# 中正确使用来自 roslyn 代码分析的 ControlFlowGraph
【发布时间】:2020-05-29 04:36:23
【问题描述】:

我不明白为什么我在下面的代码中遇到错误(使用 VS2017)与找不到应该是 Microsoft.CodeAnalysis.FlowAnalysis 包的一部分的类 ControlFlowGraph 相关:

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

【问题讨论】:

    标签: c# visual-studio roslyn roslyn-code-analysis control-flow-graph


    【解决方案1】:

    当我使用具有正确版本的 roslyn CodeAnalysis 包时,我能够解决问题:

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

    目标框架是.NETFramework 4.7.2

    在 roslyn Github repo 上为此问题创建的已关闭问题的链接是 here

    【讨论】:

      【解决方案2】:

      根据我的测试,我发现我可以使用类 ControlFlowGraph。

      我安装了以下 nugetpackage。

      Microsoft.代码分析

      Microsoft.Build.Locator

      然后,您将看到以下结果。

      此外,我使用了 .net 框架 4.6.1。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-11
        相关资源
        最近更新 更多