Roslyn Analyzer 分析命名空间

tri*_*god 4 c# roslyn roslyn-code-analysis

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

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

我们正在讨论具有 > 1m 行代码和近 35000 种类型的解决方案。所以性能确实很重要。

我想做的事:

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

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

Tie*_*ies 6

Roslyn 分析器可以注册一堆不同的代码操作,例如。在“整个文件”级别,方法、每个语法节点或符号。根据您确切要分析的内容,其中任何一个都可能适用于您。特别是,正如您所指出的,您担心性能。查看AnalysisContext.Register*Action()方法,了解您可以添加的可能的“钩子”。

得到你想要的东西:

1 获取当前类

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

context.RegisterSyntaxNodeAction(AnalyzeClassNode, SyntaxKind.ClassDeclaration);
Run Code Online (Sandbox Code Playgroud)

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

2 获取当前类的命名空间

为此,您需要语义模型。假设您使用了该RegisterSyntaxNodeAction方法,并声明了一个方法AnalyzeClassNode,然后在主体中,您可以执行以下操作:

var classNode = context.Node;
var model = context.SemanticModel;
var classSymbol = model.GetDeclaredSymbol(classNode);
Run Code Online (Sandbox Code Playgroud)

你得到命名空间符号:

var @namespace = classSymbol.ContainingNamespace;
Run Code Online (Sandbox Code Playgroud)

而且.MetadataName会给你的命名空间的字符串。

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

这是更复杂的事情,实际上取决于您在这里尝试实现的目标。真正得到诸如“所有依赖类型或导入”之类的东西。您应该遍历整个类节点,获取每个有用节点的符号(我不知道这会带来什么),并检查它的命名空间或完整的元数据名称。

也许,您可以对此进行详细说明,以了解这是否是正确的方法。


顺便说一句,请查看“立即学习 Roslyn”,这是一个包含大量 Roslyn 教程的站点。具体来说,您要查看第 3 部分(针对语法节点)、第 7 部分(针对符号)和第 10 部分(分析器介绍)。