Roslyn /查找参考文献 - 无法正确加载Workspace

时间:2014-04-18 19:14:31

标签: c# static-analysis roslyn mono.cecil

我正在尝试编写一些代码来查找任何给定方法的所有方法调用,因为我正在寻找创建开源UML序列图表工具。但是,我遇到了麻烦,超过了前几行代码:/

API似乎发生了巨大变化,我似乎无法通过查看代码来推断出正确的用法。

当我这样做时:

    var workspace = new CustomWorkspace();
    string solutionPath = @"C:\Workspace\RoslynTest\RoslynTest.sln";
    var solution = workspace.CurrentSolution;

我发现workspace.CurrentSolution有0个项目。我认为这将等同于之前Workspace.LoadSolution( string solutionFile ),它可能会包含解决方案中的任何项目,但我没有在此路径中找到任何成功。

我非常困惑0.o

如果有人可以提供一些关于如何使用FindReferences API来识别特定方法的所有调用的额外指导,那将非常感谢!

或者,我会采取静态分析方法吗?我想支持lambdas,迭代器方法和异步等。

=============================================== =====================

编辑 -

以下是基于已接受答案的完整示例:

using System.Linq;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.MSBuild;
using Microsoft.CodeAnalysis.FindSymbols;
using System.Diagnostics;

namespace RoslynTest
{
    class Program
    {
        static void Main(string[] args)
        {
            string solutionPath = @"C:\Workspace\RoslynTest\RoslynTest.sln";
            var workspace = MSBuildWorkspace.Create();
            var solution = workspace.OpenSolutionAsync(solutionPath).Result;
            var project = solution.Projects.Where(p => p.Name == "RoslynTest").First();
            var compilation = project.GetCompilationAsync().Result;
            var programClass = compilation.GetTypeByMetadataName("RoslynTest.Program");

            var barMethod = programClass.GetMembers("Bar").First();
            var fooMethod = programClass.GetMembers("Foo").First();

            var barResult = SymbolFinder.FindReferencesAsync(barMethod, solution).Result.ToList();
            var fooResult = SymbolFinder.FindReferencesAsync(fooMethod, solution).Result.ToList();

            Debug.Assert(barResult.First().Locations.Count() == 1);
            Debug.Assert(fooResult.First().Locations.Count() == 0);
        }

        public bool Foo()
        {
            return "Bar" == Bar();
        }

        public string Bar()
        {
            return "Bar";
        }
    }
}

3 个答案:

答案 0 :(得分:9)

CustomWorkspace

  

允许手动添加项目和文档的工作区。

由于您尝试加载解决方案,因此应使用MSBuildWorkspace

  

可以通过打开MSBuild解决方案和项目文件来填充的工作区。

您可以使用MSBuildWorkspace创建新的solutionPath并致电OpenSolutionAsync。有关参考查找部分,请查看SymbolFinder

答案 1 :(得分:2)

解决方案是MSBuild概念。

您需要创建MSBuildWorkspace并致电OpenSolutionAsync()

答案 2 :(得分:1)

string solutionPath = @"C:\Workspace\RoslynTest\RoslynTest.sln";

创建一个局部变量。它对您的CustomWorkspace对象没有影响。