2014-04-18 11 views
6

Próbuję napisać kod, aby znaleźć wszystkie wywołania metody danej metody jak szukam do stworzenia open source narzędzia UML diagramów. Mam jednak problem z przedostaniem się przez pierwsze kilka wierszy kodu:/Roslyn/Znajdź odnośników - Nie można poprawnie załadować Workspace

Wygląda na to, że interfejs API uległa drastycznej zmianie i nie potrafię określić właściwego zastosowania, patrząc na kod.

Kiedy zrobić:

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

Uważam, że workspace.CurrentSolution ma 0 projektach. Pomyślałem, że to będzie odpowiednik tego, co wcześniej było Workspace.LoadSolution(string solutionFile), które rzekomo zawierało jakiekolwiek Projekty w Rozwiązaniu, ale nie znajduję żadnych sukcesów na tej ścieżce.

Jestem strasznie zdezorientowany 0.o

Jeśli ktoś może oferować dodatkowe wytyczne, w jaki sposób mogę korzystać z FindReferences API zidentyfikować wszystkie wywołania konkretnej metody, byłoby bardzo mile widziane!

Alternatywnie, byłbym lepiej biorąc podejście statyczna analiza? Chciałbym wspierać takie rzeczy, jak lambdy, metody iteracyjne i asynchroniczne.

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

Edit -

Oto pełny przykład na podstawie zaakceptowanej odpowiedzi:

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"; 
     } 
    } 
} 
+0

Wypróbowałem Twoje rozwiązanie i natknąłem się na tę właściwość "CanOpenDocuments" przypisaną jako false w Rozwiązaniu-> Przestrzeń robocza-> CanOpenDocuments Co zrobiłem źle?Rozwiązanie –

+0

może być nieaktualne - zaktualizuj wątek – Jordan

Odpowiedz

9

CustomWorkspace jest

Obszar roboczy, który pozwala na ręczne dodawanie projektów i dokumentów.

Ponieważ próbujesz załadować rozwiązanie, należy użyć MSBuildWorkspace, który jest

Obszar roboczy, które mogą być wypełniane przez otwarcie rozwiązań projektowych i MSBuild plików.

Można utworzyć nowy MSBuildWorkspace i nazywają OpenSolutionAsync z solutionPath. Aby zapoznać się z częścią dotyczącą odniesienia, spójrz na numer SymbolFinder.

+0

@DavirdPoeschl Jeśli nie znam nazwy rozwiązania podczas pracy z analizatorem, w jaki sposób mogę pobierać dynamicznie? –

+0

@KevinAvignon Jeśli jesteś w analizatorze, potrzebujesz tylko informacji dostarczonych przez API (węzeł lub symbol składniowy do analizy i pewien kontekst). Czego potrzebujesz poza tym, co zostało dostarczone? Jeśli masz jakiś scenariusz, zastanów się nad stworzeniem dla niego osobnego pytania. –

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

tworzy zmienną lokalną. Nie ma to wpływu na twój obiekt CustomWorkspace.

Powiązane problemy