Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Roslyn / Find References - Can't properly load Workspace

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";
        }
    }
}
like image 849
Jordan Avatar asked Apr 18 '14 19:04

Jordan


3 Answers

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.

like image 157
David Poeschl Avatar answered Nov 07 '22 03:11

David Poeschl


Solutions are an MSBuild concept.

You need to create an MSBuildWorkspace and call OpenSolutionAsync().

like image 2
SLaks Avatar answered Nov 07 '22 04:11

SLaks


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

creates a local variable. It has no influence on your CustomWorkspace object.

like image 1
Ben Voigt Avatar answered Nov 07 '22 04:11

Ben Voigt