Roslyn Analyzer 分析命名空间

Roslyn Analyzer analyze Namespaces

我们有一些准则,我们希望如何使用我们的命名空间,并且对它们也有访问限制。因为有时开发人员会做错,所以我们需要分析这些规则。目前我们正在用 nDepend 做这件事,效果很好。但是,有人必须监督这个过程,找到违反这些规则的人并强迫他修复它,这个过程非常耗时。因此,在开发过程中或至少在构建当前更改之后立即得到通知会非常好。这应该是 roslyn 分析器的工作。

在过去的 3 个小时里,我已经对 roslyn 进行了自我介绍,但我对功能列表及其工作方式有点不知所措。也许你可以给我一个提示,我怎样才能实现我想要的。

我们讨论的是超过 100 万行代码和近 35000 种类型的解决方案。所以性能确实很重要。

我想做的事情:

  1. 获取当前class
  2. 获取当前class
  3. 的命名空间
  4. 获取所有使用过的类型及其全名

如果我能做到这一点,剩下的就相对容易了。我玩过它,也许我需要打开的 class 和编译的当前项目。但是打开这个非常耗时,因此性能会很差。

Roslyn 分析器可以注册一堆不同的代码操作,例如。在 "whole file" 级别,方法、每个语法节点或符号。根据您确切要分析的内容,其中任何一个都可能适用于您。特别是,正如您所指出的,您很关心性能。请参阅 AnalysisContext.Register*Action() 方法,可能 "hooks" 您可以添加。

得到你想要的东西:

1 获取当前class

基本上,对于其中任何一个,您应该能够获得当前的 class(如果注册语法节点或符号操作),或所有声明的 classes(例如,通过注册编译操作或语法树操作)。但最简单的选择是为 class 节点注册一个语法节点分析,你可以这样做:

context.RegisterSyntaxNodeAction(AnalyzeClassNode, SyntaxKind.ClassDeclaration);

其中AnalyzeClassNode是分析class声明的动作。这将接收一个额外的上下文(SyntaxNodeAnalysisContext),其中包含 class 声明语法节点。

2 获取当前class

的命名空间

为此,您需要语义模型。假设您使用了 RegisterSyntaxNodeAction 方法,并声明了一个方法 AnalyzeClassNode,那么在正文中,您可以这样做:

var classNode = context.Node;
var model = context.SemanticModel;
var classSymbol = model.GetDeclaredSymbol(classNode);

你得到命名空间符号:

var @namespace = classSymbol.ContainingNamespace;

并且 .MetadataName 将为您提供字符串形式的命名空间。

3 获取所有使用过的类型及其全名

这要复杂得多,而且实际上取决于您要在此实现的目标。真正达到 "all dependent types, or imports" 之类的目标。您应该遍历整个 class 节点,获取每个有用节点的符号(我不知道这会带来什么),并检查它的命名空间或完整的元数据名称。

或许,您可以详细说明一下,看看这是否是正确的方法。


顺便说一句,请查看 "Learn Roslyn Now",这是一个包含大量 Roslyn 教程的网站。具体来说,您需要查看第 3 部分(语法节点)、第 7 部分(符号)和第 10 部分(分析器介绍)。