问题
I'm trying to write some code to find all method invocations of any given method as I am looking to create an open source UML Sequence Diagramming tool. I'm having trouble, however, getting past the first few lines of code :/
The API appears to have changed drastically and I can't seem to infer proper usage by looking at the code.
When I do:
var workspace = new CustomWorkspace();
string solutionPath = @"C:\Workspace\RoslynTest\RoslynTest.sln";
var solution = workspace.CurrentSolution;
I find that workspace.CurrentSolution has 0 Projects. I figured this would be the equivalent to what was previously Workspace.LoadSolution( string solutionFile )
which would then supposedly contain any Projects in the Solution, but I am not finding any success with this path.
I am terribly confused 0.o
If someone could offer some additional guidance as to how I can use the FindReferences API to identify all invocations of a particular method, it would be very much appreciated!
Alternatively, would I be better off taking a static-analysis approach? I would like to support things like lambdas, iterator methods and async.
====================================================================
Edit -
Here is a full example based on the accepted answer:
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";
}
}
}
回答1:
CustomWorkspace is
A workspace that allows manual addition of projects and documents.
Since you're trying to load a solution, you should use the MSBuildWorkspace, which is
A workspace that can be populated by opening MSBuild solution and project files.
You can create a new MSBuildWorkspace
and call OpenSolutionAsync with your solutionPath
. For the reference finding part, take a look at the SymbolFinder.
回答2:
Solutions are an MSBuild concept.
You need to create an MSBuildWorkspace
and call OpenSolutionAsync().
回答3:
string solutionPath = @"C:\Workspace\RoslynTest\RoslynTest.sln";
creates a local variable. It has no influence on your CustomWorkspace
object.
来源:https://stackoverflow.com/questions/23160685/roslyn-find-references-cant-properly-load-workspace