2016-08-30 2 views
2

Я успешно получаю зависимости между проектами с Roslyn, и теперь мне хотелось бы получить зависимости между классами, аналогично функции Code Map в Visual Studio Enterprise.Получить зависимости между классами в Roslyn

Вот мой код, "?????" часть - это то место, где я могу себе представить. Однако я очень новичок в API Roslyn, и я не знаю, как исходить оттуда.

 Solution solution = MSBuildWorkspace.Create() 
      .OpenSolutionAsync(Path.Combine(repoRootFolder, "MySolution.sln")) 
      .Result; 

     ProjectDependencyGraph projdeps = solution.GetProjectDependencyGraph(); 

     Digraph graph = new Digraph(); 

     foreach (ProjectId projectId in projdeps.GetTopologicallySortedProjects()) 
     { 
      string projName = solution.GetProject(projectId).Name; 
      var projDeps = projdeps.GetProjectsThatThisProjectDirectlyDependsOn(projectId); 
      foreach (ProjectId depId in projDeps) 
      { 
       Project dep = solution.GetProject(depId); 

       Compilation compilation = dep.GetCompilationAsync().Result; 

       foreach (var syntree in compilation.SyntaxTrees) 
       { 
        foreach (var classNode in syntree.GetRoot().DescendantNodes().OfType<ClassDeclarationSyntax>()) 
        { 
         var classesThisClassNodeReferences = ????????? 
        } 
       } 

       string depName = dep.Name; 

       graph.Dependencies.Add(new Dependency 
       { 
        Source = projName, 
        Target = depName 
       }); 
      } 
     } 
+0

Вы хотите получать все использованные типы, используя это 'ClassDeclarationSyntax'? Вы можете получить все 'SyntaxNode', получить соответствующий 'ISymbol' через семантическую модель, проверить, является ли этот символ' INamedTypeSymbol' или нет. Но я думаю, что это будет очень медленно. – Tamas

+0

@ Tamas-SonarSourceTeam Мне нужно генерировать графики зависимостей и выводить их в PDF, поэтому, если он медленный, это не прерыватель транзакций. Но я все еще не мог понять, как выполнить операцию, которую вы предлагаете. Не могли бы вы разместить какой-то код в качестве ответа? Это очень помогло бы мне, и я как можно скорее проверил бы мой сценарий. – heltonbiker

ответ

1

Я не уверен, что ваши требования, но вы, вероятно, можете пойти для проверки всех потомков SyntaxNode S класса и получить соответствующий символ, и это тип, а затем собрать эти типы. Что-то вроде следующего:

Обратите внимание, что там может быть несколько typesForCurrentClass для данного класса символа из-за частичных классов.

+0

Это сработало, но оно дает мне тип _every_, который использует классы, даже .Net-типы, ints, строки и т. Д. CodeMap (функция VS Enterprise, которую я пытаюсь реплицировать) обычно ставит такие вещи внутри группы «Внешние», но я не заинтересован в этих зависимостях. Знаете ли вы, как заставить 'typesForCurrentClass' содержать только типы, определенные в решении? Спасибо за интерес! – heltonbiker

+0

Я не уверен, вы можете проверить 'type.ContainingAssembly' и посмотреть, есть ли там что-нибудь полезное. – Tamas

Смежные вопросы