【问题标题】:Get dependencies between classes in Roslyn获取 Roslyn 中类之间的依赖关系
【发布时间】:2017-01-07 04:30:18
【问题描述】:

我用 Roslyn 成功获取了项目之间的依赖关系,现在我想获取类之间的依赖关系,类似于 Visual Studio Enterprise 中的 Code Map 功能。

这是我的代码,“???????”部分是我想我可以得到一些东西的地方。不过,我对 Roslyn API 很陌生,我不知道如何从那里开始。

        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
                });
            }
        }

【问题讨论】:

  • 您的意思是使用ClassDeclarationSyntax 获取所有使用过的类型吗?你可以得到所有的SyntaxNodes,通过语义模型得到对应的ISymbol,检查符号是否为INamedTypeSymbol。但我认为这会非常缓慢。
  • @Tamas-SonarSourceTeam 我需要生成依赖关系图并将它们输出到 PDF,所以如果速度很慢,它不会破坏交易。但我仍然无法弄清楚如何执行您建议的操作。您能否发布一些代码作为答案?这对我有很大帮助,我会尽快在我的实际场景中进行测试。
  • @heltonbiker 你的有向图使用什么库?
  • @farlee2121 我自己创建了一个类,其实很粗糙,here's the gist
  • @heltonbiker 你可能也对我发现的 CodeMap 的这个开源替代品感兴趣 github.com/zebmason/DeepEnds

标签: c# roslyn roslyn-code-analysis


【解决方案1】:

我不确定您的要求,但是您可能可以检查该类的所有后代SyntaxNodes 并获取相应的符号,以及它的类型,然后收集这些类型。类似于以下内容:

var semantic = compilation.GetSemanticModel(syntree);
var typesForCurrentClass = classNode.DescendantNodes().Select(n => 
  semantic.GetTypeInfo(n).Type);

请注意,由于部分类,给定类符号可以有多个typesForCurrentClass

【讨论】:

  • 它有效,但它为我提供了类使用的每个类型,甚至是.Net类型、整数、字符串等。 CodeMap(我正在尝试的 VS Enterprise 功能复制)通常将这种东西放在“外部”组中,但我目前对这些依赖项没有兴趣。你知道让typesForCurrentClass 只包含解决方案中定义的类型的方法吗?感谢您的关注!
  • 我不确定,你可以查看type.ContainingAssembly,看看那里有什么有用的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-16
  • 2016-09-10
  • 2010-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多