Roslyn分析器分析命名空间。

4

我们有一些指南,规定了如何使用命名空间,并对其进行访问限制。由于开发人员有时会做错,我们需要分析这些规则。目前我们正在使用nDepend进行此操作,效果不错。但是,必须监督此过程,找到违反这些规则的人并强制他修复问题,这需要很长时间。因此,在开发过程中或者至少在构建当前更改之后,能够获得即时通知将是非常好的。这应该是roslyn分析器的工作。

我已经花了3个小时研究roslyn,但是我对其功能列表和工作方式感到有些不知所措。也许您可以给我一个提示,告诉我如何实现我想要的功能。

我们正在谈论具有超过1m行代码和近35000个类型的解决方案。因此,性能是非常重要的。

我想要做的是:

  1. 获取当前类
  2. 获取当前类的命名空间
  3. 获取所有使用的带有完整名称的类型

如果我能够做到这一点,其他事情将相对容易。我已经试过了,也许我需要打开正在编辑的类的当前项目和编译。但是,打开这些内容需要很长时间,因此性能会非常差。


你有持续集成服务器吗?你应该能够在每次提交时运行NDepend(以及任何其他检查,如单元测试)。 - svick
1个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
7
一个Roslyn分析器可以注册许多不同的代码操作,例如在“整个文件”级别、方法、每个单独的语法节点或符号上。根据您要分析的内容,其中任何一个都可能适用于您。特别是,正如您所指出的,您关心性能。请参见AnalysisContext.Register*Action()方法,以获取您可以添加的可能的“钩子”。 为了获得您想要的内容:

1 获取当前类

基本上,使用任何一种方法,您应该能够获取当前类(如果注册语法节点或符号操作),或者所有声明的类(例如,通过注册编译操作或语法树操作)。但最简单的选项是为类节点注册语法节点分析,您可以这样做:
context.RegisterSyntaxNodeAction(AnalyzeClassNode, SyntaxKind.ClassDeclaration);

当使用AnalyzeClassNode分析类的声明时,需接收额外的上下文(SyntaxNodeAnalysisContext),其中包含类声明的语法节点。

2 获取当前类的命名空间

为此,需要使用语义模型。假设您使用了RegisterSyntaxNodeAction方法,并声明了一个名为AnalyzeClassNode的方法,则在其函数体内,可以这样实现:

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

你可以通过以下方式获取命名空间符号:

var @namespace = classSymbol.ContainingNamespace;

.MetadataName将以字符串形式给出命名空间。

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

这是一件更加复杂的事情,真正取决于您在此处想要实现什么。为了真正做到像“所有依赖类型或导入”之类的东西,您应该遍历整个类节点,获取每个有用节点的符号(我不知道那将包括什么),并检查其命名空间或完整元数据名称。

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


顺便说一下,请看一下"Learn Roslyn Now",这是一个有关Roslyn的教程网站。具体来说,您需要查看第三部分(用于语法节点)、第七部分(用于符号)和第十部分(引入分析器)。


谢谢你的非常好的回答!我会检查你给我的链接,并在我知道我要做什么时回来。我不知道它是否有帮助:我们想限制对我们自己代码中命名空间(以我们公司名称开头的命名空间)的访问。除了一些框架内容外,只允许访问层次结构向上或到第三级,因为我们有类似于[company] . [module] . [feature]的东西。每个人都可以访问功能,但不能访问其子项。如果您违反此规则,"即时"提示将非常甜美。 - trialgod
顺便说一下,我无法实际运行我的代码,因为我是在我的 Mac 上编写的。如果代码有问题,请让我知道,这样我就可以更新答案。也许明天我能够在我的工作电脑上验证这些示例。 - Ties
1
这可能是一个很好的情况,你应该只使用语义模型,如果它太慢了,那么再回头看看。过早优化等等。 - Jason Malinowski
我现在有一个可用的版本,感谢你的帮助。我还有一个问题。我们通过Nuget分发分析器。有没有一种方法可以显示错误,但不会中断构建?Info不显示任何消息,警告和错误会导致构建中断。还有其他选项吗? - trialgod
实际上,是有的。使用分析器有两种方式:NuGet 和 VSIX。如果将其添加为 NuGet 分析器,则会中断构建。但是,如果将其安装为 VSIX,则只会提供“智能感知”错误,但不会中断构建(尽管它将对每个解决方案都处于活动状态)。顺便说一句,如果这个方法确实对你有用,也许你可以将答案标记为已接受 ;) - Ties
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,