我们有一些指导方针,我们希望如何使用我们的名称空间,也有对它们的访问限制。因为开发人员有时会做错,所以我们需要分析这些规则。目前,我们正在用nDepend做这件事,它工作得很好。但要有人监督这个过程,找到违反这些规则的人,强迫他改正,这是非常耗时的。因此,在开发过程中或至少在构建当前更改之后获得即时通知将是非常好的。这应该是roslyn分析仪的工作。
我在过去的3个小时里向roslyn介绍了自己,但是我对功能列表和它们的工作方式有点不知所措。也许你能给我一个提示,怎样才能达到我想要的。
我们讨论的是一个包含> 100万行代码和近35000个类型的解决方案。所以性能确实很重要。
我想做什么:
- 获取当前类
- 获取当前类的命名空间
- 获取所有已使用的类型及其全名
如果我能做到这一点,剩下的就相对容易了。我已经玩弄了它,也许我需要打开类和编译的当前项目。但是打开这个非常耗时,因此性能会非常难看。
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教程的网站。具体来说,您需要检出第3部分(语法节点)、第7部分(符号)和第10部分(分析器介绍)。